2012-04-21 5 views
29

मुझे दिए गए इकाई ऑब्जेक्ट के लिए property1 और property2 को छोड़कर सभी फ़ील्ड अपडेट करने की आवश्यकता है।एंटीटी फ्रेमवर्क और EntityState का उपयोग कर किसी ऑब्जेक्ट के प्रत्येक फ़ील्ड को अपडेट करने के लिए कैसे करें। संशोधित

[HttpPost] 
    public ActionResult Add(object obj) 
    { 
     if (ModelState.IsValid) 
     { 
       context.Entry(obj).State = System.Data.EntityState.Modified; 

       context.SaveChanges();    
     } 
     return View(obj); 
    } 

कैसे इस कोड के साथ अद्यतन नहीं किया जा रहा के लिए obj.property1 के लिए एक अपवाद और obj.property2 जोड़ने के लिए इसे बदलने के लिए:
इस कोड को हो रही है?

उत्तर

57

मान लेते हैं कि आप गुण का एक संग्रह बाहर रखा जाना करने के लिए है कि दो:

var excluded = new[] { "property1", "property2" }; 
EF5 साथ

.NET 4.5 पर आप यह कर सकते हैं:

var entry = context.Entry(obj); 
entry.State = EntityState.Modified; 
foreach (var name in excluded) 
{ 
    entry.Property(name).IsModified = false; 
} 

यह .NET 4.5 पर EF5 की एक नई सुविधा का उपयोग करता है जो किसी प्रॉपर्टी को संशोधित करने के लिए सेट किए जाने के बाद भी संशोधित नहीं किया जा सकता है।

एफई 4.3.1 या .NET 4 पर EF5 का उपयोग करते समय आप इस के बजाय कर सकते हैं:

var entry = context.Entry(obj); 
foreach (var name in entry.CurrentValues.PropertyNames.Except(excluded)) 
{ 
    entry.Property(name).IsModified = true; 
} 
+1

.NET 4.5 में अच्छा सुधार, धन्यवाद! – Slauma

+0

हाँ। इसका उल्लेख है कि नेट 4.5 – mohamadreza

+0

में मुझे पता है कि यह निहित है, लेकिन मैं बस स्पष्ट रूप से यह कहना चाहता था कि ईएफ 4.3.1 के लिए - आप प्रवेश सेट नहीं कर सकते हैं। प्रॉपर्टी (...)। IsModified = false; - यह संकलित होगा, लेकिन ऐसा करने का प्रयास करते समय आपको रनटाइम त्रुटि मिल जाएगी। इसलिए मुझे लगता है कि ईएफ 4.3.1 के लिए यह कहना उचित है कि आपको केवल सकारात्मक शब्दों का उपयोग करना चाहिए, दूसरे शब्दों में: आप केवल चीजों को संशोधित (सत्य) के रूप में चिह्नित कर सकते हैं क्योंकि वे पहले ही संशोधित (झूठी) के रूप में सेट हैं। ईएफ 5 आपको स्वतंत्र रूप से सही/गलत सेट करने की अनुमति देता है; – dyslexicanaboko

19

आप इस तरह के अपवाद को परिभाषित नहीं कर सकते हैं। लेकिन आप एकल गुण चिह्नित कर सकते हैं के रूप में संशोधित:

context.Entry(obj).Property(o => o.Property3).IsModified = true; 
context.Entry(obj).Property(o => o.Property4).IsModified = true; 
// etc. 

ध्यान दें कि false को IsModified की स्थापना समर्थित नहीं है एक बार आप Modified करने के लिए पूरे इकाई के राज्य चिह्नित किया है।

अपने उद्देश्य के लिए मैं वास्तव में डेटाबेस से इकाई लोड और फिर सामान्य परिवर्तन ट्रैकिंग का उपयोग कर इसे अद्यतन करने के लिए पसंद करेंगे:

var objInDB = context.Objects.Single(o => o.Id == obj.Id); 

obj.Property1 = objInDB.Property1; 
obj.Property2 = objInDB.Property2; 

context.Entry(objInDB).CurrentValues.SetValues(obj); 

context.SaveChanges(); 
+1

मैं अपने 2 कोड ब्लॉक जो झूठा बयान का उपयोग नहीं कर का एक अच्छा रिवर्स समाधान है पसंद है। निम्नलिखित के लिए – mohamadreza

+1

+1: "ध्यान दें कि एक बार गलत करने के लिए IsModified सेटिंग को समर्थित नहीं किया गया है जब आप पूरी इकाई की स्थिति को संशोधित करने के लिए चिह्नित कर चुके हैं।" –

+0

मैंने यहां एक समान नोट देखा: https://msdn.microsoft.com/en-us/library/jj592677(v=vs.113).aspx जो कहता है "वर्तमान में किसी व्यक्तिगत संपत्ति को रीसेट करना संभव नहीं है इसे संशोधित के रूप में चिह्नित करने के बाद संशोधित किया गया है। यह कुछ ऐसा है जिसे हम भावी रिलीज में समर्थन देने की योजना बना रहे हैं। " हालांकि जब मैंने कोशिश की तो यह काम करता था। हो सकता है कि msdn पृष्ठ पुराना हो, हालांकि यह कहता है कि इसे 23 अक्टूबर, 2016 को अपडेट किया गया था। – KevinVictor

9

यह सवाल पहले से ही अच्छी तरह से जवाब था, लेकिन मैं करना चाहते हैं, जो किसी के लिए भी एक विस्तार विधि प्रदान करना चाहता था इसका इस्तेमाल करें।

इस कोड एफई 4.3.1

के लिए विकसित किया गया था
//You will need to import/use these namespaces  
using System.Data.Entity; 
using System.Data.Entity.Infrastructure;  

//Update an entity object's specified columns, comma separated 
//This method assumes you already have a context open/initialized 
public static void Update<T>(this DbContext context, T entityObject, params string[] properties) where T : class 
{ 
    context.Set<T>().Attach(entityObject); 

    var entry = context.Entry(entityObject); 

    foreach(string name in properties) 
     entry.Property(name).IsModified = true; 

    context.SaveChanges(); 
} 

प्रयोग उदाहरण

using (FooEntities context = new FooEntities()) 
{ 
    FooEntity ef = new FooEntity(); 

    //For argument's sake say this entity has 4 columns: 
    // FooID (PK), BarID (FK), Name, Age, CreatedBy, CreatedOn 

    //Mock changes 
    ef.FooID = 1; 
    ef.Name = "Billy"; 
    ef.Age = 85; 

    context.Update<FooEntity>(ef, "Name", "Age"); //I only want to update Name and Age 
} 
0

ऊपर जवाब (उनमें से ज्यादातर) DbContext का उपयोग करें। ऑब्जेक्ट कॉन्टेक्स्ट का उपयोग करने वाले लोगों के लिए ये समाधान उपलब्ध नहीं हैं।

यहाँ ObjectContext सख्ती से (EF5 .NET 4.5) के लिए समाधान है:

ctx.AddObject("ENTITYNAME", item); 
ctx.ObjectStateManager.ChangeObjectState(item, EntityState.Modified); 

var entry = ctx.ObjectStateManager.GetObjectStateEntry(item); 
entry.RejectPropertyChanges("PROPERTY_TO_EXCLUDE"); 
संबंधित मुद्दे