2013-07-05 6 views
6

मैं इकाई की रूपरेखा 5. का उपयोग करता है कुछ स्थानों में एक MVC आवेदन मैं एक कोड है कि बनाता है या संस्थाओं को अद्यतन करता है और फिर अपडेट किए गए डेटा पर कार्रवाई किसी तरह का प्रदर्शन करने के लिए है । उन कार्यों में से कुछ नेविगेशन गुणों तक पहुंच की आवश्यकता है और मैं उन्हें रीफ्रेश करने के लिए नहीं मिल सकता।इकाई की रूपरेखा 5 - इसके तत्काल बाद DbContext ताज़ा के बाद बचत में परिवर्तन

यहाँ उदाहरण है (सरलीकृत कोड रहा है)

मॉडल

class User : Model 
{ 
    public Guid Id { get; set; } 
    public string Name { get; set; } 
} 

class Car : Model 
{ 
    public Guid Id { get; set; } 
    public Guid DriverId { get; set; } 
    public virtual User Driver { get; set; } 

    [NotMapped] 
    public string DriverName 
    { 
     get { return this.Driver.Name; } 
    } 
} 

नियंत्रक

public CarController 
{ 
    public Create() 
    { 
     return this.View(); 
    } 

    [HttpPost] 
    public Create(Car car) 
    { 
     if (this.ModelState.IsValid) 
     { 
      this.Context.Cars.Create(booking); 
      this.Context.SaveChanges(); 

      // here I need to access some of the resolved nav properties 
      var test = booking.DriverName; 
     } 

     // error handling (I'm removing it in the example as it's not important) 
    } 
} 

उदाहरण के ऊपर बनाएं विधि के लिए है, लेकिन मैं यह भी है अद्यतन विधि के साथ एक ही समस्या जो बहुत समान है, यह सिर्फ लेता है GET कार्रवाई और दुकानों में संदर्भ यह POST कार्रवाई में Update विधि का उपयोग करने से आपत्ति है।

public virtual void Create(TObject obj) 
{ 
    return this.DbSet.Add(obj); 
} 

public virtual void Update(TObject obj) 
{ 
    var currentEntry = this.DbSet.Find(obj.Id); 
    this.Context.Entry(currentEntry).CurrentValues.SetValues(obj); 
    currentEntry.LastModifiedDate = DateTime.Now; 
} 

अब मैं कई अलग पद्धतियां कि मैं googled या ढेरों पर पाया लेकिन कुछ भी मेरे लिए काम किया जा रहा है की कोशिश की है।

मेरे नवीनतम प्रयास में मैंने SaveChanges विधि को कॉल करने और डेटाबेस से डेटा की आवश्यकता के बाद एक पुनः लोड करने की कोशिश की है। मैंने जो किया है वह यहां है।

मैं वस्तु संदर्भ ताज़ा करने के लिए SaveChanges विधि ovewrite प्रदान करते ही बचाने

public int SaveChanges() 
{ 
    var rowsNumber = this.Context.SaveChanges(); 
    var objectContext = ((IObjectContextAdapter)this.Context).ObjectContext; 
    objectContext.Refresh(RefreshMode.StoreWins, this.Context.Bookings); 

    return rowsNumber; 
} 

मैं अद्यतन वस्तु डेटा प्राप्त करने की कोशिश की है तुरंत अपने HTTPCreate और Update में SaveChanges कॉल के बाद कोड की इस पंक्ति जोड़कर क्रियाएं:

car = this.Context.Cars.Find(car.Id); 

दुर्भाग्यवश नेविगेशन प्रॉपर्टी अभी भी null है। डेटा को संशोधित करने के तुरंत बाद मैं डीबीकॉन्टेक्स्ट को ठीक से रीफ्रेश कैसे कर सकता हूं?

संपादित

मैं मूल रूप से मैं एक समाधान है, लेकिन यह बदसूरत है और मैं यह पसंद नहीं है कि उल्लेख करना भूल गया। मैं जाँच कर सकते हैं जब भी मैं नेविगेशन संपत्ति का उपयोग करता है, तो यह null है और अगर यह है मैं मैन्युअल रूप से नए DbContext डेटा बना सकते हैं और अद्यतन कर सकते हैं। लेकिन मैं वास्तव में इस तरह हैक्स से बचना चाहूंगा।

class Car : Model 
{  
    [NotMapped] 
    public string DriverName 
    { 
     get 
     { 
      if (this.Driver == null) 
      { 
       using (var context = new DbContext()) 
       { 
        this.Driver = this.context.Users.Find(this.DriverId); 
       } 
      } 

      return this.Driver.Name; 
     } 
    } 
} 

उत्तर

4

समस्या शायद इस तथ्य है कि आइटम आप संदर्भ के लिए जोड़ रहे हैं आलसी लोड करने के लिए आवश्यक घटक के साथ एक proxy नहीं है की वजह से है। यहां तक ​​कि SaveChanges() बुला के बाद आइटम एक प्रॉक्सी उदाहरण में बदल नहीं होगा।

मैं तुम्हें DbSet उपयोग करने का प्रयास सुझाव देते हैं।() विधि बना सकते हैं और इकाई को तार पर प्राप्त से सभी मूल्यों भर में कॉपी:

public virtual TObject Create(TObject obj) 
{ 
    var newEntry = this.DbSet.Create(); 
    this.Context.Entry(newEntry).CurrentValues.SetValues(obj); 
    return newEntry; 
} 

अद्यतन

तो SetValues() एक मुद्दा तो मैं सुझाव दे रहा है आप स्थानांतरित करना automapper कोशिश पर नए प्रॉक्सी इंस्टेंस में Add से पहले बनाए गए प्रॉक्सी से बनाए गए प्रॉक्सी से डेटा। कुछ इस तरह:

private bool mapCreated = false; 
public virtual TObject Create(TObject obj) 
{ 
    var newEntry = this.DbSet.Create(); 

    if (!mapCreated) 
    { 
     Mapper.CreateMap(obj.GetType(), newEntry.GetType()); 
     mapCreated = true; 
    } 
    newEntry = Mapper.Map(obj, newEntry); 

    this.DbSet.Add(newEntry; 
    return newEntry; 
} 
+0

मेरी 'Update' विधि के बारे में? क्या मुझे मूल वस्तु को 'this.Context.Cars.Find (id)' के अलावा अन्य प्राप्त करना चाहिए? – RaYell

+0

'Find' डेटाबेस से प्रॉक्सी ऑब्जेक्ट लौटाएगा, लेकिन यदि आप इस ऑब्जेक्ट को स्थानीय रूप से जोड़े गए ऑब्जेक्ट को ढूंढ रहे हैं और अपडेट कर रहे हैं तो यह आपके द्वारा जो ऑब्जेक्ट जोड़ा गया है उसे मिलेगा। – qujck

+0

मैंने आपके समाधान का पालन करने की कोशिश की लेकिन वह मुझे 'System.InvalidOperationException: सदस्य' CurrentValues ​​'को' कार 'प्रकार की इकाई के लिए नहीं बुलाया जा सकता क्योंकि इकाई संदर्भ में मौजूद नहीं है। संदर्भ में एक इकाई जोड़ने के लिए DbSet की जोड़ें या अटैच विधि को कॉल करें। 'मैंने इसे जोड़ा है। कॉन्टैक्ट.सेट ()। (नया एंटर्री);' आपकी पहली पंक्ति के ठीक बाद और अब मुझे ' System.InvalidOperationException: संपत्ति 'आईडी' ऑब्जेक्ट की मुख्य जानकारी का हिस्सा है और इसे संशोधित नहीं किया जा सकता है। – RaYell

0

मैं अगले तरीके का उपयोग: इकाई को अलग कर फिर से लोड

public T Reload<T>(T entity) where T : class, IEntityId 
{ 
    ((IObjectContextAdapter)_dbContext).ObjectContext.Detach(entity); 
    return _dbContext.Set<T>().FirstOrDefault(x => x.Id == entity.Id); 
} 
संबंधित मुद्दे