के साथ रिपोजिटरी पैटर्न मुझे अभी भी रिपोजिटरी पैटर्न के साथ कुछ भ्रम है। मैं इस पैटर्न का उपयोग करने का प्राथमिक कारण डोमेन से ईएफ 4.1 विशिष्ट डेटा एक्सेस ऑपरेशन को कॉल करना से बचाना है। मैं एक आईरिपोजिटरी इंटरफेस से जेनेरिक सीआरयूडी ऑपरेशन को कॉल करना चाहता हूं। इससे परीक्षण आसान हो जाएगा और अगर मुझे भविष्य में डेटा एक्सेस फ्रेमवर्क को कभी भी बदलना है, तो मैं बहुत सारे कोड को दोबारा किए बिना ऐसा करने में सक्षम हूं।इकाई फ्रेमवर्क 4.1 और अभिभावक/बाल संबंध
मैं डेटाबेस में 3 टेबल है: Group
, Person
, और GroupPersonMap
यहाँ मेरी स्थिति का एक उदाहरण है। GroupPersonMap
एक लिंक तालिका है और इसमें Group
और Person
प्राथमिक कुंजी शामिल हैं। मैंने वीएस 2010 डिजाइनर के साथ 3 टेबलों का ईएफ मॉडल बनाया। ईएफ GroupPersonMap
मानने के लिए पर्याप्त स्मार्ट था एक लिंक टेबल है, इसलिए यह इसे डिजाइनर में नहीं दिखाता है। मैं ईएफ के जेनरेट किए गए वर्गों की बजाय अपने मौजूदा डोमेन ऑब्जेक्ट्स का उपयोग करना चाहता हूं ताकि मैं मॉडल के लिए कोड जनरेशन बंद कर दूं।
public interface IRepository<T> where T: class
{
IQueryable<T> GetAll();
T Add(T entity);
T Update(T entity);
void Delete(T entity);
void Save()
}
और एक सामान्य एफई भंडार:
public class EF4Repository<T> : IRepository<T> where T: class
{
public DbContext Context { get; private set; }
private DbSet<T> _dbSet;
public EF4Repository(string connectionString)
{
Context = new DbContext(connectionString);
_dbSet = Context.Set<T>();
}
public EF4Repository(DbContext context)
{
Context = context;
_dbSet = Context.Set<T>();
}
public IQueryable<T> GetAll()
{
// code
}
public T Insert(T entity)
{
// code
}
public T Update(T entity)
{
Context.Entry(entity).State = System.Data.EntityState.Modified;
Context.SaveChanges();
}
public void Delete(T entity)
{
// code
}
public void Save()
{
// code
}
}
public class Group
{
public int GroupId { get; set; }
public string Name { get; set; }
public virtual ICollection<Person> People { get; set; }
}
public class Person
{
public int PersonId {get; set; }
public string FirstName { get; set; }
public virtual ICollection<Group> Groups { get; set; }
}
मैं बहुत की तरह एक सामान्य भंडार इंटरफेस है:
कि एफई मॉडल से मिलान मेरे मौजूदा कक्षाएं इस प्रकार हैं
अब मान लीजिए कि मैं मौजूदापर मौजूदा Group
को मानचित्र बनाना चाहता हूं। मैं निम्नलिखित की तरह कुछ करने के लिए होता है:
EFRepository<Group> groupRepository = new EFRepository<Group>("name=connString");
EFRepository<Person> personRepository = new EFRepository<Person>("name=connString");
var group = groupRepository.GetAll().Where(g => g.GroupId == 5).First();
var person = personRepository.GetAll().Where(p => p.PersonId == 2).First();
group.People.Add(person);
groupRepository.Update(group);
लेकिन क्योंकि एफई सोचता Person
नया है यह काम नहीं करता है, और INSERT
डेटाबेस में Person
जो एक प्राथमिक कुंजी बाधा त्रुटि का कारण होगा फिर से करने की कोशिश करेंगे । मुझे DbSet
की Attach
विधि का उपयोग ईएफ को बताने के लिए करना चाहिए कि Person
डेटाबेस में पहले से मौजूद है, इसलिए और Person
के बीच के बीच एक नक्शा बनाएं।
तो आदेश संदर्भ के लिए Person
संलग्न करने के लिए अब मैं अपने IRepository के लिए एक Attach
विधि जोड़नी होगी में:
EFRepository<Group> groupRepository = new EFRepository<Group>("name=connString");
EFRepository<Person> personRepository = new EFRepository<Person>(groupRepository.Context);
var group = groupRepository.GetAll().Where(g => g.GroupId == 5).First();
var person = personRepository.GetAll().Where(p => p.PersonId == 2).First();
personRepository.Attach(person);
group.People.Add(person);
groupRepository.Update(group);
फिक्स्ड:
public interface IRepository<T> where T: class
{
// existing methods
T Attach(T entity);
}
प्राथमिक कुंजी बाधा त्रुटि को ठीक करने। अब मुझे किसी अन्य मुद्दे से निपटना होगा जहां हर बार जब मैं समूह/व्यक्ति मानचित्र बनाता हूं तो डेटाबेस में Group
डेटाबेस में अद्यतन किया जा रहा है। ऐसा इसलिए है क्योंकि मेरी EFRepository.Update()
विधि में, इकाई स्थिति स्पष्ट रूप से Modified'. I must set the Group's state to
पर अपरिवर्तित so the
समूह की तालिका संशोधित नहीं होती है।
इसे ठीक करने के मैं, Group
Update
मेरी IRepository लिए अधिभार कि जड़ इकाई को अपडेट नहीं है, या किसी प्रकार जोड़ना होगा इस मामले में:
public interface IRepository<T> where T: class
{
// existing methods
T Update(T entity, bool updateRootEntity);
}
अद्यतन विधि के EF4 implentation कुछ ऐसा दिखाई देगा इस तरह:
T Update(T entity, bool updateRootEntity)
{
if (updateRootEntity)
Context.Entry(entity).State = System.Data.EntityState.Modified;
else
Context.Entry(entity).State = System.Data.EntityState.Unchanged;
Context.SaveChanges();
}
मेरा प्रश्न है: क्या मैं इसे सही तरीके से देख रहा हूं? मेरा रिपोजिटरी ईएफ केंद्रित दिखना शुरू कर रहा है क्योंकि मैं ईएफ और रिपोजिटरी पैटर्न के साथ काम करना शुरू कर देता हूं। इस लंबी पोस्ट को पढ़ने के लिए धन्यवाद
+1 ग्रेट उत्तर –
+1 इकाई ढांचे + काम की इकाई के लिए बहुत जानकारीपूर्ण –
+1। भंडारों को एक ही dbcontext साझा करने की आवश्यकता है। मैं शर्त लगाता हूं कि मेरी समस्या यही है। – Jhayes2118