সত্তা ফ্রেমওয়ার্ক ব্যবহার করে "যদি আপডেট সারি উপস্থিত থাকে তবে তা যদি অন্য কোনও সন্নিবেশ করানো হয়" প্রয়োগ করার সবচেয়ে কার্যকরী উপায়ের বিষয়ে কারও কাছে পরামর্শ রয়েছে?
সত্তা ফ্রেমওয়ার্ক ব্যবহার করে "যদি আপডেট সারি উপস্থিত থাকে তবে তা যদি অন্য কোনও সন্নিবেশ করানো হয়" প্রয়োগ করার সবচেয়ে কার্যকরী উপায়ের বিষয়ে কারও কাছে পরামর্শ রয়েছে?
উত্তর:
আপনি যদি সংযুক্ত বস্তু (প্রসঙ্গের একই উদাহরণ থেকে লোড হওয়া বস্তু) নিয়ে কাজ করছেন তবে আপনি কেবল ব্যবহার করতে পারেন:
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 প্রসঙ্গটি ধ্বংস করতে অপেক্ষা করার কোন সমস্যা নেই?
সত্তা ফ্রেমওয়ার্ক ৪.৩ অনুসারে, AddOrUpdate
নেমস্পেসে একটি পদ্ধতি রয়েছে System.Data.Entity.Migrations
:
public static void AddOrUpdate<TEntity>(
this IDbSet<TEntity> set,
params TEntity[] entities
)
where TEntity : class
যা ডক দ্বারা :
যখন SaveChanges বলা হয় তখন কী দ্বারা সত্তা যুক্ত করে বা আপডেট করে। ডাটাবেস পরিভাষা থেকে "আপসেট" অপারেশনের সমান। মাইগ্রেশন ব্যবহার করে ডেটা সিড করার সময় এই পদ্ধতিটি কার্যকর হতে পারে।
@ স্ম্যাশিং ১৯78৮ এর মন্তব্যের জবাব দিতে , আমি @ কলিনের সরবরাহিত লিঙ্ক থেকে প্রাসঙ্গিক অংশগুলি পেস্ট করব
অ্যাডঅরআপটেটের কাজ হ'ল বিকাশের সময় ডেটা বীজ করার সময় আপনি সদৃশ তৈরি করবেন না তা নিশ্চিত করা।
প্রথমত, এটি আপনার ডাটাবেজে একটি রেকর্ড সন্ধানের জন্য একটি কোয়েরি কার্যকর করবে যেখানে আপনি কী (প্রথম প্যারামিটার) হিসাবে সরবরাহ করেছেন তা অ্যাডঅরআপেটে সরবরাহিত ম্যাপযুক্ত কলাম মান (বা মান) এর সাথে মেলে। সুতরাং এটি মিলে যাওয়ার জন্য কিছুটা আলগা-গুজি তবে ডিজাইনের সময় ডেটা বীজের জন্য পুরোপুরি সূক্ষ্ম।
আরও গুরুত্বপূর্ণ, যদি কোনও মিল খুঁজে পাওয়া যায় তবে আপডেটটি সমস্ত আপডেট হয়ে যায় এবং আপনার অ্যাডআরআপটেটে যা ছিল না তা বাতিল করে দেয়।
এটি বলেছিল, আমার এমন একটি পরিস্থিতি রয়েছে যেখানে আমি কোনও বাহ্যিক পরিষেবা থেকে ডেটা টানছি এবং প্রাথমিক কী দ্বারা বিদ্যমান মানগুলি সন্নিবেশ করিয়ে বা আপডেট করছি (এবং গ্রাহকদের জন্য আমার স্থানীয় ডেটা কেবল পঠনযোগ্য) - AddOrUpdate
এখন upd মাসেরও বেশি সময় ধরে উত্পাদন ব্যবহার করা হচ্ছে এখনও কোন সমস্যা।
কল করার সময় যাদুটি ঘটে 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
অবশ্যই কোনও শ্রেণীর ক্ষেত্র হতে পারে, বা পদ্ধতিটি স্থিতিশীল এবং একটি এক্সটেনশন তৈরি করা যেতে পারে তবে এটি মূল বিষয়গুলি।
লাডিসালভের উত্তর নিকটে ছিল তবে ইএফ 6 (ডাটাবেস-প্রথম) এ কাজ করতে আমাকে বেশ কয়েকটি পরিবর্তন করতে হয়েছিল ifications আমি আমার অ্যাডআরআপডেট পদ্ধতিতে আমার ডেটা প্রসঙ্গে প্রসারিত করেছি এবং এখনও অবধি এটি বিচ্ছিন্ন বস্তুর সাথে ভালভাবে কাজ করছে বলে মনে হচ্ছে:
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);
}
}
[....]
আমার মতে এটি বলার অপেক্ষা রাখে না যে সদ্য প্রকাশিত সত্তা ফ্রেমওয়ার্ক কোডের জন্য সত্তা প্রকাশিত এনটিটিগ্রাফফেরেশনগুলির সাথে প্রথমে আপনি গ্রাফের সমস্ত সত্তার রাজ্যগুলির সংজ্ঞা দেওয়ার জন্য কিছু পুনরাবৃত্ত কোড লিখতে নিজেকে বাঁচাতে পারেন। আমি এই পণ্যটির লেখক। এবং আমি এটি গিথুব , কোড-প্রকল্পে প্রকাশ করেছি ( একটি ধাপে ধাপে বিক্ষোভ অন্তর্ভুক্ত এবং একটি নমুনা প্রকল্প ডাউনলোডের জন্য প্রস্তুত) এবং নুগেট ।
এটা করবে না স্বয়ংক্রিয়ভাবে সত্ত্বা রাজ্যের সেট করতে 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();
}
}
@ লাডিস্লাভ মির্ণা উত্তরের বিকল্প। এটি যদি সত্তা ফ্রেমওয়ার্কের জন্য 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();
}