दिलचस्प पोस्ट
मेरे रेल ऐप के लिए कस्टम कॉन्फ़िग विकल्प बनाने का सर्वोत्तम तरीका? Mysql2 को स्थापित करने में त्रुटि: मणि देशी एक्सटेंशन बनाने में विफल PHP में तिथि के अनुसार सॉर्ट करें बड़ी सीएसवी फ़ाइल पर स्मृति का पायथन (numpy) MYSQL एक सम्मिलित वक्तव्य में अधिकतम दिनांक चुनें कैसे एक MongoDB दस्तावेज़ की _id अद्यतन? दूसरा कॉल करने के लिए 2 कॉलम का उपयोग करके Vlookup "प्रतीक्षा_फ़ेंस: उत्तर प्राप्त करने में विफल: 10004003"? कैसे WPF विंडो में बंद करें बटन छिपाने के लिए? InvokeRequired कोड पैटर्न को स्वचालित करना सप्ताह के पहले दिन NSCalendar एक क्लाइंट पर एकाधिक SSH निजी कुंजी का उपयोग करने का सर्वोत्तम तरीका बैकस्लैश वर्ण (\\) क्या है? क्या आप चुन सकते हैं जब एक UITableViewCell पर एक ऊंचाई परिवर्तन चेतन? वर्ग के नाम से तत्व कैसे प्राप्त करें?

इकाई फ़्रेमवर्क का उपयोग कर केवल एक फ़ील्ड को कैसे अपडेट करें?

यहाँ तालिका है

उपयोगकर्ता

UserId UserName Password EmailAddress 

और कोड ..

 public void ChangePassword(int userId, string password){ //code to update the password.. } 

वेब के समाधान से एकत्रित समाधान "इकाई फ़्रेमवर्क का उपयोग कर केवल एक फ़ील्ड को कैसे अपडेट करें?"

लाडीस्लाव का जवाब डीबीसीटीन्टेक्स (ईएफ 4.1 में पेश किया गया) का उपयोग करने के लिए अद्यतन:

 public void ChangePassword(int userId, string password) { var user = new User() { Id = userId, Password = password }; using (var db = new MyEfContextName()) { db.Users.Attach(user); db.Entry(user).Property(x => x.Password).IsModified = true; db.SaveChanges(); } } 

आप ईएफ को बता सकते हैं कि किस प्रकार गुणों को इस तरह अद्यतन किया जाना है:

 public void ChangePassword(int userId, string password) { var user = new User { Id = userId, Password = password }; using (var context = new ObjectContext(ConnectionString)) { var users = context.CreateObjectSet<User>(); users.Attach(user); context.ObjectStateManager.GetObjectStateEntry(user) .SetModifiedProperty("Password"); context.SaveChanges(); } } 

आपके पास मूल रूप से दो विकल्प हैं:

  • ईएफ तरीके से सभी तरह से जाना, उस मामले में, आप करेंगे
    • प्रदान किए गए उपयोगकर्ता userId आधार पर वस्तु लोड करें – संपूर्ण ऑब्जेक्ट लोड हो जाता है
    • password फ़ील्ड अपडेट करें
    • ऑब्जेक्ट को संदर्भ का उपयोग करके वापस सहेजें। .SaveChanges() विधि

इस मामले में, यह ईएफ पर निर्भर है कि यह कैसे विस्तार से निपटूं। मैंने अभी परीक्षण किया है, और इस मामले में मैं केवल एक ऑब्जेक्ट के एक फ़ील्ड को बदलता हूं, जो ईएफ बनाता है वह बहुत ज्यादा है जो आपने मैन्युअल रूप से बनाया था, भी – जैसे कुछ:

 `UPDATE dbo.Users SET Password = @Password WHERE UserId = @UserId` 

इसलिए ईएफ पर्याप्त रूप से समझने के लिए काफी चालाक है कि कॉलम वास्तव में किस प्रकार बदल गए हैं, और यह वास्तव में जरूरी उन अपडेट को संभालने के लिए टी-एसक्यूएल कथन बनाएगा।

  • आप एक संग्रहीत कार्यविधि को परिभाषित करते हैं जो टी-एसक्यूएल कोड में है (केवल दिए गए UPDATE dbo.Users SET Password = @Password WHERE UserId = @UserId लिए Password कॉलम को अपडेट करें और कुछ और नहीं – मूल रूप से UPDATE dbo.Users SET Password = @Password WHERE UserId = @UserId ) को निष्पादित करता है और आप अपने ईएफ मॉडल में उस संग्रहीत कार्यविधि के लिए एक फ़ंक्शन आयात बनाएं और आप ऊपर बताए गए चरणों को करने के बजाय इस फ़ंक्शन को कॉल करते हैं

मैं इसका उपयोग कर रहा हूं:

इकाई:

 public class Thing { [Key] public int Id { get; set; } public string Info { get; set; } public string OtherStuff { get; set; } } 

dbcontext:

 public class MyDataContext : DbContext { public DbSet<Thing > Things { get; set; } } 

एक्सेसर कोड:

 MyDataContext ctx = new MyDataContext(); // FIRST create a blank object Thing thing = ctx.Things.Create(); // SECOND set the ID thing.Id = id; // THIRD attach the thing (id is not marked as modified) db.Things.Attach(thing); // FOURTH set the fields you want updated. thing.OtherStuff = "only want this field updated."; // FIFTH save that thing db.SaveChanges(); 

इस समस्या के समाधान के लिए खोज करते समय, मुझे पैनट्रिक डेजर्डिन्स के ब्लॉग के माध्यम से गोनेले के उत्तर में एक बदलाव आया:

 public int Update(T entity, Expression<Func<T, object>>[] properties) { DatabaseContext.Entry(entity).State = EntityState.Unchanged; foreach (var property in properties) { var propertyName = ExpressionHelper.GetExpressionText(property); DatabaseContext.Entry(entity).Property(propertyName).IsModified = true; } return DatabaseContext.SaveChangesWithoutValidation(); } 

" जैसा कि आप देख सकते हैं, यह इसके दूसरे पैरामीटर के रूप में एक फ़ंक्शन का अभिव्यक्ति लेता है.यह एक लम्बाडा अभिव्यक्ति में निर्दिष्ट करके इस पद्धति का उपयोग करने देगा जो संपत्ति को अपडेट कर देगी। "

 ...Update(Model, d=>d.Name); //or ...Update(Model, d=>d.Name, d=>d.SecondProperty, d=>d.AndSoOn); 

(कुछ हद तक एक समान समाधान यहां दिया गया है: https://stackoverflow.com/a/5749469/2115384 )

यह विधि मैं वर्तमान में अपने स्वयं के कोड में उपयोग कर रहा हूं , यह भी (Linq) अभिव्यक्ति प्रकार ExpressionType.Convert को नियंत्रित करने के लिए विस्तारित है। यह मेरे मामले में आवश्यक था, उदाहरण के लिए Guid और अन्य ऑब्जेक्ट गुणों के साथ वे कन्वर्ट () में 'लिपटे' थे और इसलिए System.Web.Mvc.ExpressionHelper.GetExpressionText । द्वारा नहीं संभाला। System.Web.Mvc.ExpressionHelper.GetExpressionText

 public int Update(T entity, Expression<Func<T, object>>[] properties) { DbEntityEntry<T> entry = dataContext.Entry(entity); entry.State = EntityState.Unchanged; foreach (var property in properties) { string propertyName = ""; Expression bodyExpression = property.Body; if (bodyExpression.NodeType == ExpressionType.Convert && bodyExpression is UnaryExpression) { Expression operand = ((UnaryExpression)property.Body).Operand; propertyName = ((MemberExpression)operand).Member.Name; } else { propertyName = System.Web.Mvc.ExpressionHelper.GetExpressionText(property); } entry.Property(propertyName).IsModified = true; } dataContext.Configuration.ValidateOnSaveEnabled = false; return dataContext.SaveChanges(); } 

मैं यहाँ खेल के लिए देर हो चुकी हूं, लेकिन मैं यह कर रहा हूं, मैं एक ऐसे समय के लिए शिकार कर रहा था, जिसके साथ मैं संतुष्ट हूं। यह केवल उन फ़ील्ड के लिए एक UPDATE स्टेटमेंट का उत्पादन करता है, जैसा कि आप स्पष्ट रूप से परिभाषित करते हैं कि वे "सफेद सूची" अवधारणा के माध्यम से क्या हैं जो वेब फ़ॉर्म इंजेक्शन को वैसे भी रोकने के लिए अधिक सुरक्षित है।

मेरे इएसेशन डेटा रिपॉजिटरी से एक अंश:

 public bool Update<T>(T item, params string[] changedPropertyNames) where T : class, new() { _context.Set<T>().Attach(item); foreach (var propertyName in changedPropertyNames) { // If we can't find the property, this line wil throw an exception, //which is good as we want to know about it _context.Entry(item).Property(propertyName).IsModified = true; } return true; } 

यह कोशिश में लपेटा जा सकता है..आपको अगर चाहें तो पकड़ लें, लेकिन मैं व्यक्तिगत रूप से इस परिदृश्य में अपवादों के बारे में जानना चाहता हूं।

इसे इस फैशन की तरह कुछ कहा जाएगा (मेरे लिए, यह एएसपी.नेट वेब एपीआई के माध्यम से था):

 if (!session.Update(franchiseViewModel.Franchise, new[] { "Name", "StartDate" })) throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound)); 

इकाई ढांचा उन वस्तुओं पर आपके परिवर्तनों को ट्रैक करता है जिन्हें आपने डेटाबेस से DbContext के माध्यम से पूछे। उदाहरण के लिए यदि आप DbContext इंस्टेंस नाम है dbContext

 public void ChangePassword(int userId, string password){ var user = dbContext.Users.FirstOrDefault(u=>u.UserId == userId); user.password = password; dbContext.SaveChanges(); } 

मुझे पता है कि यह एक पुरानी धागा है, लेकिन मैं भी इसी तरह के समाधान की तलाश कर रहा था और समाधान के साथ जाने का निर्णय लिया @ डॉकू-तो प्रदान किया। मैं @ इमरान रिजवी द्वारा पूछे गए प्रश्न का उत्तर देने के लिए टिप्पणी कर रहा हूं, मैंने डॉकू @ लिंक का अनुसरण किया जो इसी प्रकार के क्रियान्वयन को दर्शाता है। @ इमरान रिजवी का सवाल यह था कि उन्हें उपलब्ध कराए गए समाधान का उपयोग करने में त्रुटि हो रही है 'लम्बे अभिव्यक्ति को टाइप' एक्सप्रेशन> [] 'में परिवर्तित नहीं किया जा सकता क्योंकि यह एक प्रतिनिधि प्रकार नहीं है' मैं @ Doku-so का समाधान करने के लिए किए गए एक छोटे संशोधन की पेशकश करना चाहता था जो इस त्रुटि को हल करता है यदि किसी और को इस पोस्ट में आता है और डॉक्यू-व्हाट्स के समाधान का उपयोग करने का निर्णय लेता है।

समस्या अद्यतन विधि में दूसरी तर्क है,

 public int Update(T entity, Expression<Func<T, object>>[] properties). 

दिए गए वाक्यविन्यास का उपयोग करके इस विधि को कॉल करने के लिए …

 Update(Model, d=>d.Name, d=>d.SecondProperty, d=>d.AndSoOn); 

आपको दूसरी परावर्तन के सामने 'पराम' कीवर्ड जोड़ना चाहिए ताकि ऐसा किया जा सके।

 public int Update(T entity, params Expression<Func<T, object>>[] properties) 

या यदि आप विधि हस्ताक्षर को बदलना नहीं चाहते हैं, तो अद्यतन विधि को कॉल करने के लिए आपको ' नया ' कीवर्ड जोड़ने की जरूरत है, सरणी के आकार को निर्दिष्ट करें, फिर अंत में प्रत्येक प्रॉपर्टी के लिए संग्रह ऑब्जेक्ट आरंभिक सिंटैक्स का उपयोग करके अपडेट किए गए अद्यतन को देखें नीचे।

 Update(Model, new Expression<Func<T, object>>[3] { d=>d.Name }, { d=>d.SecondProperty }, { d=>d.AndSoOn }); 

@ डॉकू-का उदाहरण में वह अभिव्यक्तियों की एक सरणी निर्दिष्ट कर रहा है ताकि आपको सरणी के अपडेट करने के लिए गुणों को पास करना होगा, क्योंकि आपको सरणी के आकार को भी निर्दिष्ट करना होगा। इससे बचने के लिए आप सरणी के बजाय IEnumerable का उपयोग करने के लिए अभिव्यक्ति तर्क भी बदल सकते हैं।

यहां मेरा Doku-so's समाधान का कार्यान्वयन है I

 public int Update<TEntity>(LcmsEntities dataContext, DbEntityEntry<TEntity> entityEntry, params Expression<Func<TEntity, object>>[] properties) where TEntity: class { entityEntry.State = System.Data.Entity.EntityState.Unchanged; properties.ToList() .ForEach((property) => { var propertyName = string.Empty; var bodyExpression = property.Body; if (bodyExpression.NodeType == ExpressionType.Convert && bodyExpression is UnaryExpression) { Expression operand = ((UnaryExpression)property.Body).Operand; propertyName = ((MemberExpression)operand).Member.Name; } else { propertyName = System.Web.Mvc.ExpressionHelper.GetExpressionText(property); } entityEntry.Property(propertyName).IsModified = true; }); dataContext.Configuration.ValidateOnSaveEnabled = false; return dataContext.SaveChanges(); } 

उपयोग:

 this.Update<Contact>(context, context.Entry(modifiedContact), c => c.Active, c => c.ContactTypeId); 

@ डॉकू- ने जेनेरिक का उपयोग करने के लिए एक शांत दृष्टिकोण प्रदान किया है, मैंने अपनी समस्या को हल करने के लिए इस अवधारणा का इस्तेमाल किया है लेकिन आप डॉक्यू-हाइज के समाधान का उपयोग नहीं कर सकते हैं और इस पोस्ट और लिंक्ड पोस्ट दोनों में उपयोग त्रुटि प्रश्नों का उत्तर नहीं दिया है।

इकाई फ़्रेमवर्क कोर में, Attach करें प्रविष्टि देता है, इसलिए आपको यह ज़रूरत है:

 var user = new User { Id = userId, Password = password }; db.Users.Attach(user).Property(x => x.Password).IsModified = true; db.SaveChanges(); 

कई सुझावों का मेल करना मैं निम्नलिखित का प्रस्ताव करता हूं:

  async Task<bool> UpdateDbEntryAsync<T>(T entity, params Expression<Func<T, object>>[] properties) where T : class { try { var entry = db.Entry(entity); db.Set<T>().Attach(entity); foreach (var property in properties) entry.Property(property).IsModified = true; await db.SaveChangesAsync(); return true; } catch (Exception ex) { System.Diagnostics.Debug.WriteLine("UpdateDbEntryAsync exception: " + ex.Message); return false; } } 

के द्वारा बुलाया गया

 UpdateDbEntryAsync(dbc, d => d.Property1);//, d => d.Property2, d => d.Property3, etc. etc.); 

या द्वारा

 await UpdateDbEntryAsync(dbc, d => d.Property1); 

या द्वारा

 bool b = UpdateDbEntryAsync(dbc, d => d.Property1).Result; 

मैं ValueInjecter nuget का प्रयोग बाध्यकारी मॉडल को डेटाबेस इकाई में निम्नलिखित का उपयोग करने के लिए इंजेक्ट करने के लिए करता हूं:

 public async Task<IHttpActionResult> Add(CustomBindingModel model) { var entity= await db.MyEntities.FindAsync(model.Id); if (entity== null) return NotFound(); entity.InjectFrom<NoNullsInjection>(model); await db.SaveChangesAsync(); return Ok(); } 

कस्टम कन्वेंशन के उपयोग की सूचना दें जो गुणों को अपडेट नहीं करता है यदि वे सर्वर से रिक्त हैं

ValueInjecter v3 +

 public class NoNullsInjection : LoopInjection { protected override void SetValue(object source, object target, PropertyInfo sp, PropertyInfo tp) { if (sp.GetValue(source) == null) return; base.SetValue(source, target, sp, tp); } } 

उपयोग:

 target.InjectFrom<NoNullsInjection>(source); 

वैल्यू इंजेक्टर वी 2

इस जवाब को देखो

चेतावनी

आप नहीं जान पाएंगे कि संपत्ति जानबूझकर रिक्त करने के लिए मंजूरी दे रही है या फिर इसका कोई मूल्य नहीं है। दूसरे शब्दों में, संपत्ति मूल्य को केवल दूसरे मान के साथ बदला जा सकता है, लेकिन साफ़ नहीं किया गया

 public async Task<bool> UpdateDbEntryAsync(TEntity entity, params Expression<Func<TEntity, object>>[] properties) { try { this.Context.Set<TEntity>().Attach(entity); EntityEntry<TEntity> entry = this.Context.Entry(entity); entry.State = EntityState.Modified; foreach (var property in properties) entry.Property(property).IsModified = true; await this.Context.SaveChangesAsync(); return true; } catch (Exception ex) { throw ex; } } 
 public void ChangePassword(int userId, string password) { var user = new User{ Id = userId, Password = password }; using (var db = new DbContextName()) { db.Entry(user).State = EntityState.Added; db.SaveChanges(); } }