क्या किसी के पास "अपडेट पंक्ति को लागू करने का सबसे कारगर तरीका है, यदि उसमें कोई और प्रविष्टि है" जो कि एंटिटी फ्रेमवर्क का उपयोग करके "तर्क" है?
क्या किसी के पास "अपडेट पंक्ति को लागू करने का सबसे कारगर तरीका है, यदि उसमें कोई और प्रविष्टि है" जो कि एंटिटी फ्रेमवर्क का उपयोग करके "तर्क" है?
जवाबों:
यदि आप संलग्न ऑब्जेक्ट (संदर्भ के एक ही उदाहरण से लोड की गई वस्तु) के साथ काम कर रहे हैं, तो आप बस उपयोग कर सकते हैं:
if (context.ObjectStateManager.GetObjectStateEntry(myEntity).State == EntityState.Detached)
{
context.MyEntities.AddObject(myEntity);
}
// Attached object tracks modifications automatically
context.SaveChanges();
यदि आप वस्तु की कुंजी के बारे में किसी भी ज्ञान का उपयोग कर सकते हैं तो आप कुछ इस तरह से उपयोग कर सकते हैं:
if (myEntity.Id != 0)
{
context.MyEntities.Attach(myEntity);
context.ObjectStateManager.ChangeObjectState(myEntity, EntityState.Modified);
}
else
{
context.MyEntities.AddObject(myEntity);
}
context.SaveChanges();
यदि आप ऑब्जेक्ट की मौजूदगी को उसकी आईडी से तय नहीं कर सकते हैं तो आपको लुकअप क्वेरी को छोड़ना होगा:
var id = myEntity.Id;
if (context.MyEntities.Any(e => e.Id == id))
{
context.MyEntities.Attach(myEntity);
context.ObjectStateManager.ChangeObjectState(myEntity, EntityState.Modified);
}
else
{
context.MyEntities.AddObject(myEntity);
}
context.SaveChanges();
usingखंड में रखा। क्या संदर्भ को थोड़ी देर के लिए स्मृति में छोड़ देना ठीक है? उदाहरण के लिए, विंडोज फॉर्म के जीवन के दौरान? मैं डेटाबेस पर न्यूनतम लोड सुनिश्चित करने के लिए सामान्य रूप से डेटाबेस ऑब्जेक्ट्स की कोशिश और सफाई करता हूं। क्या मेरे EF संदर्भ को नष्ट करने के लिए कोई समस्या नहीं है?
एंटिटी फ्रेमवर्क 4.3 के अनुसार, AddOrUpdateनामस्थान पर एक विधि है System.Data.Entity.Migrations:
public static void AddOrUpdate<TEntity>(
this IDbSet<TEntity> set,
params TEntity[] entities
)
where TEntity : class
डॉक्टर द्वारा :
SaveChanges कहे जाने पर कुंजी द्वारा संस्थाओं को जोड़ता या अद्यतन करता है। डेटाबेस शब्दावली से एक "तेज" ऑपरेशन के बराबर। माइग्रेशन का उपयोग करते हुए डेटा सीडिंग करते समय यह विधि उपयोगी हो सकती है।
@ Smashing1978 द्वारा टिप्पणी का जवाब देने के लिए , मैं @Colin द्वारा प्रदान किए गए लिंक से प्रासंगिक भागों को चिपकाऊंगा
AddOrUpdate का काम यह सुनिश्चित करना है कि जब आप विकास के दौरान डेटा बीज करते हैं तो आप डुप्लिकेट नहीं बनाते हैं।
सबसे पहले, यह आपके डेटाबेस में एक क्वेरी को निष्पादित करेगा जो एक रिकॉर्ड की तलाश में है जहाँ आपने एक कुंजी (प्रथम पैरामीटर) के रूप में आपूर्ति की है जो AddOrUpdate में आपूर्ति किए गए मैप किए गए स्तंभ मान (या मान) से मेल खाती है। तो यह मिलान के लिए थोड़ा ढीला-ढाला है, लेकिन डिजाइनिंग समय डेटा के लिए पूरी तरह से ठीक है।
इससे भी महत्वपूर्ण बात यह है कि यदि कोई मिलान पाया जाता है, तो अपडेट सभी को अपडेट करेगा और आपके AddOrUpdate में किसी भी तरह का शून्य नहीं करेगा।
उस ने कहा, मेरे पास एक ऐसी स्थिति है जहां मैं एक बाहरी सेवा से डेटा खींच रहा हूं और प्राथमिक कुंजी (और उपभोक्ताओं के लिए मेरा स्थानीय डेटा केवल-पढ़ने के लिए) द्वारा मौजूदा मूल्यों को सम्मिलित या अपडेट कर रहा है - AddOrUpdateअब और 6 महीने से अधिक समय से उत्पादन में उपयोग कर रहा है कोई समस्या नहीं है।
कॉल करते समय जादू होता है SaveChanges()और करंट पर निर्भर करता है EntityState। यदि इकाई में ए है EntityState.Added, तो इसे डेटाबेस में जोड़ा जाएगा, अगर इसमें ए है, तो इसे EntityState.Modifiedडेटाबेस में अपडेट किया जाएगा। तो आप InsertOrUpdate()निम्नानुसार एक विधि लागू कर सकते हैं:
public void InsertOrUpdate(Blog blog)
{
using (var context = new BloggingContext())
{
context.Entry(blog).State = blog.BlogId == 0 ?
EntityState.Added :
EntityState.Modified;
context.SaveChanges();
}
}
यदि आप Id = 0यह निर्धारित करने के लिए जाँच नहीं कर सकते हैं कि यह एक नई संस्था है या नहीं, तो लद्दिस्लाव मिन्का के उत्तर की जाँच करें ।
यदि आप जानते हैं कि आप एक ही संदर्भ का उपयोग कर रहे हैं और किसी भी संस्था को अलग नहीं कर रहे हैं, तो आप इस तरह से एक सामान्य संस्करण बना सकते हैं:
public void InsertOrUpdate<T>(T entity, DbContext db) where T : class
{
if (db.Entry(entity).State == EntityState.Detached)
db.Set<T>().Add(entity);
// If an immediate save is needed, can be slow though
// if iterating through many entities:
db.SaveChanges();
}
db निश्चित रूप से एक वर्ग क्षेत्र हो सकता है, या विधि को स्थिर और एक विस्तार बनाया जा सकता है, लेकिन यह मूल बातें है।
लादिस्लाव का जवाब करीब था लेकिन मुझे EF6 (डेटाबेस-प्रथम) में काम करने के लिए कुछ संशोधन करने पड़े। मैंने AddOrUpdate पद्धति पर अपना डेटा संदर्भ बढ़ाया और अब तक यह अलग वस्तुओं के साथ अच्छी तरह से काम करता प्रतीत होता है:
using System.Data.Entity;
[....]
public partial class MyDBEntities {
public void AddOrUpdate(MyDBEntities ctx, DbSet set, Object obj, long ID) {
if (ID != 0) {
set.Attach(obj);
ctx.Entry(obj).State = EntityState.Modified;
}
else {
set.Add(obj);
}
}
[....]
मेरी राय में यह कहने योग्य है कि एंटिटी फ्रेमवर्क कोड के लिए नए जारी किए गए EntityGraphOperations के साथ पहले आप ग्राफ में सभी संस्थाओं के राज्यों को परिभाषित करने के लिए कुछ दोहराए जाने वाले कोड लिखने से खुद को बचा सकते हैं। मैं इस उत्पाद का लेखक हूं। और मैंने इसे जीथब , कोड-प्रोजेक्ट ( एक चरण-दर-चरण प्रदर्शन और एक नमूना परियोजना डाउनलोड करने के लिए तैयार है) और नगेट में प्रकाशित किया है ।
यह स्वचालित रूप से Addedया के लिए संस्थाओं की स्थिति निर्धारित करेगा Modified। और आप मैन्युअल रूप से चुनेंगे कि किन संस्थाओं को हटा दिया जाना चाहिए अगर यह मौजूद नहीं है।
उदाहरण:
मान लीजिए कि मुझे एक Personवस्तु मिली है । Personकई फोन, एक दस्तावेज़ और एक पति या पत्नी हो सकता है।
public class Person
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string MiddleName { get; set; }
public int Age { get; set; }
public int DocumentId {get; set;}
public virtual ICollection<Phone> Phones { get; set; }
public virtual Document Document { get; set; }
public virtual PersonSpouse PersonSpouse { get; set; }
}
मैं उन सभी संस्थाओं की स्थिति को निर्धारित करना चाहता हूं जो ग्राफ में शामिल हैं।
context.InsertOrUpdateGraph(person)
.After(entity =>
{
// Delete missing phones.
entity.HasCollection(p => p.Phones)
.DeleteMissingEntities();
// Delete if spouse is not exist anymore.
entity.HasNavigationalProperty(m => m.PersonSpouse)
.DeleteIfNull();
});
जैसा कि आप जानते हैं कि अद्वितीय महत्वपूर्ण गुण फ़ोन इकाई की स्थिति को परिभाषित करते समय भूमिका निभा सकते हैं। ऐसे विशेष उद्देश्यों के लिए हमारे पास ExtendedEntityTypeConfiguration<>वर्ग है, जो विरासत में मिला है EntityTypeConfiguration<>। अगर हम इस तरह के विशेष विन्यासों का उपयोग करना चाहते हैं तो हमें अपनी मैपिंग कक्षाओं से विरासत में लेनी चाहिए ExtendedEntityTypeConfiguration<>, बजाय EntityTypeConfiguration<>। उदाहरण के लिए:
public class PhoneMap: ExtendedEntityTypeConfiguration<Phone>
{
public PhoneMap()
{
// Primary Key
this.HasKey(m => m.Id);
…
// Unique keys
this.HasUniqueKey(m => new { m.Prefix, m.Digits });
}
}
बस इतना ही।
दोनों को और अपडेट डालें
public void InsertUpdateData()
{
//Here TestEntities is the class which is given from "Save entity connection setting in web.config"
TestEntities context = new TestEntities();
var query = from data in context.Employee
orderby data.name
select data;
foreach (Employee details in query)
{
if (details.id == 1)
{
//Assign the new values to name whose id is 1
details.name = "Sanjay";
details. Surname="Desai";
details.address=" Desiwadi";
}
else if(query==null)
{
details.name="Sharad";
details.surname=" Chougale ";
details.address=" Gargoti";
}
}
//Save the changes back to database.
context.SaveChanges();
}
किसी के साथ मौजूदा पंक्ति की जाँच करें।
public static void insertOrUpdateCustomer(Customer customer)
{
using (var db = getDb())
{
db.Entry(customer).State = !db.Customer.Any(f => f.CustomerId == customer.CustomerId) ? EntityState.Added : EntityState.Modified;
db.SaveChanges();
}
}
वैकल्पिक के लिए @LadislavMrnka उत्तर। अगर यह एंटिटी फ्रेमवर्क 6.2.0 के लिए है।
यदि आपके पास एक विशिष्ट DbSetऔर एक आइटम है जिसे या तो अद्यतन या निर्मित करने की आवश्यकता है:
var name = getNameFromService();
var current = _dbContext.Names.Find(name.BusinessSystemId, name.NameNo);
if (current == null)
{
_dbContext.Names.Add(name);
}
else
{
_dbContext.Entry(current).CurrentValues.SetValues(name);
}
_dbContext.SaveChanges();
हालाँकि यह DbSetएकल प्राथमिक कुंजी या समग्र प्राथमिक कुंजी के साथ सामान्य के लिए भी उपयोग किया जा सकता है ।
var allNames = NameApiService.GetAllNames();
GenericAddOrUpdate(allNames, "BusinessSystemId", "NameNo");
public virtual void GenericAddOrUpdate<T>(IEnumerable<T> values, params string[] keyValues) where T : class
{
foreach (var value in values)
{
try
{
var keyList = new List<object>();
//Get key values from T entity based on keyValues property
foreach (var keyValue in keyValues)
{
var propertyInfo = value.GetType().GetProperty(keyValue);
var propertyValue = propertyInfo.GetValue(value);
keyList.Add(propertyValue);
}
GenericAddOrUpdateDbSet(keyList, value);
//Only use this when debugging to catch save exceptions
//_dbContext.SaveChanges();
}
catch
{
throw;
}
}
_dbContext.SaveChanges();
}
public virtual void GenericAddOrUpdateDbSet<T>(List<object> keyList, T value) where T : class
{
//Get a DbSet of T type
var someDbSet = Set(typeof(T));
//Check if any value exists with the key values
var current = someDbSet.Find(keyList.ToArray());
if (current == null)
{
someDbSet.Add(value);
}
else
{
Entry(current).CurrentValues.SetValues(value);
}
}
संशोधित
public static void InsertOrUpdateRange<T, T2>(this T entity, List<T2> updateEntity)
where T : class
where T2 : class
{
foreach(var e in updateEntity)
{
context.Set<T2>().InsertOrUpdate(e);
}
}
public static void InsertOrUpdate<T, T2>(this T entity, T2 updateEntity)
where T : class
where T2 : class
{
if (context.Entry(updateEntity).State == EntityState.Detached)
{
if (context.Set<T2>().Any(t => t == updateEntity))
{
context.Set<T2>().Update(updateEntity);
}
else
{
context.Set<T2>().Add(updateEntity);
}
}
context.SaveChanges();
}