সত্তা ফ্রেমওয়ার্কের সাথে অন্য সন্নিবেশ যুক্তি উপস্থিত থাকলে সারি আপডেট করুন


179

সত্তা ফ্রেমওয়ার্ক ব্যবহার করে "যদি আপডেট সারি উপস্থিত থাকে তবে তা যদি অন্য কোনও সন্নিবেশ করানো হয়" প্রয়োগ করার সবচেয়ে কার্যকরী উপায়ের বিষয়ে কারও কাছে পরামর্শ রয়েছে?


2
এটি এমন একটি যা সঞ্চিত পদ্ধতিতে ডাটাবেস ইঞ্জিন স্তরে করা উচিত। অন্যথায়, আপনাকে কোনও লেনদেনে সনাক্ত / আপডেট / সন্নিবেশ করতে হবে।
স্টিফেন চুং

1
@ স্টিফেন: আসলে এটিই আমি শেষ করেছিলাম। ধন্যবাদ।
জোনাথন উড

জনাথন, আপনার প্রশ্নটি আমার পক্ষে খুব কার্যকর। আপনি কেন একটি সঞ্চিত পদ্ধতিতে স্যুইচ করেছেন?
আনার খলিলভ

2
@ আনার: এটি কেবল সহজ ছিল এবং আমি আরও দক্ষতার প্রত্যাশা করি।
জোনাথন উড

আপনার কি প্রতিটি টেবিলের জন্য একটি সঞ্চিত পদ্ধতি লিখতে হবে?
tofutim

উত্তর:


174

আপনি যদি সংযুক্ত বস্তু (প্রসঙ্গের একই উদাহরণ থেকে লোড হওয়া বস্তু) নিয়ে কাজ করছেন তবে আপনি কেবল ব্যবহার করতে পারেন:

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 প্রসঙ্গটি ধ্বংস করতে অপেক্ষা করার কোন সমস্যা নেই?
জোনাথন উড

এই চেক করুন: stackoverflow.com/questions/3653009/... বস্তুর প্রসঙ্গ যতটা সম্ভব সংক্ষিপ্ত হিসাবে কিন্তু winforms ক্ষেত্রে অথবা এই wpf থাকা উচিৎ অর্থ করতে পারেন যে প্রেক্ষাপটে উপস্থাপক হিসাবে যতদিন বসবাস করছেন। লিঙ্কযুক্ত প্রশ্নে উইনফর্মগুলিতে নিবারনেট সেশনটি ব্যবহার সম্পর্কে এমএসডিএন নিবন্ধের লিঙ্ক রয়েছে। একই পদ্ধতির প্রসঙ্গে ব্যবহার করা যেতে পারে।
লাডিস্লাভ মৃঙ্কা

1
তবে যদি আমার অবজেক্টগুলির একটি তালিকা দিয়ে এটি করার দরকার হয় ... আমার ডাটাবেসে একই আইডির সাথে সারিগুলির একটি তালিকা রয়েছে এবং আমি উপস্থিত থাকি বা প্রতিস্থাপন করতে চাই যদি তারা না থাকে তবে আমি কীভাবে করব? ধন্যবাদ!
ফিনিক্স_উই

1
এই উত্তরটি দুর্দান্ত দেখায়, তবে আমি আপডেটে এই সমস্যাটি নিয়ে চলেছি: অবজেক্টস্টেটম্যানেজারে একই কী সহ একটি বস্তু ইতিমধ্যে বিদ্যমান। অবজেক্টস্টেট ম্যানেজার একই কী দিয়ে একাধিক অবজেক্ট ট্র্যাক করতে পারে না।
জন জুমব্রাম

1
দেখে মনে হচ্ছে যে বিদ্যমান অবজেক্টটি আনার সাথে আমার কেবল কিছুটা সমস্যা হয়েছিল যাতে আপডেটটি করার আগে এর কীটি পুনরুদ্ধার করতে পারে; অনুসন্ধানের অবজেক্টটিকে বিচ্ছিন্ন করে প্রথমে এটি ঠিক করতে সহায়তা করে।
জন জুমব্রাম

33

সত্তা ফ্রেমওয়ার্ক ৪.৩ অনুসারে, AddOrUpdateনেমস্পেসে একটি পদ্ধতি রয়েছে System.Data.Entity.Migrations:

public static void AddOrUpdate<TEntity>(
    this IDbSet<TEntity> set,
    params TEntity[] entities
)
where TEntity : class

যা ডক দ্বারা :

যখন SaveChanges বলা হয় তখন কী দ্বারা সত্তা যুক্ত করে বা আপডেট করে। ডাটাবেস পরিভাষা থেকে "আপসেট" অপারেশনের সমান। মাইগ্রেশন ব্যবহার করে ডেটা সিড করার সময় এই পদ্ধতিটি কার্যকর হতে পারে।


@ স্ম্যাশিং ১৯78৮ এর মন্তব্যের জবাব দিতে , আমি @ কলিনের সরবরাহিত লিঙ্ক থেকে প্রাসঙ্গিক অংশগুলি পেস্ট করব

অ্যাডঅরআপটেটের কাজ হ'ল বিকাশের সময় ডেটা বীজ করার সময় আপনি সদৃশ তৈরি করবেন না তা নিশ্চিত করা।

প্রথমত, এটি আপনার ডাটাবেজে একটি রেকর্ড সন্ধানের জন্য একটি কোয়েরি কার্যকর করবে যেখানে আপনি কী (প্রথম প্যারামিটার) হিসাবে সরবরাহ করেছেন তা অ্যাডঅরআপেটে সরবরাহিত ম্যাপযুক্ত কলাম মান (বা মান) এর সাথে মেলে। সুতরাং এটি মিলে যাওয়ার জন্য কিছুটা আলগা-গুজি তবে ডিজাইনের সময় ডেটা বীজের জন্য পুরোপুরি সূক্ষ্ম।

আরও গুরুত্বপূর্ণ, যদি কোনও মিল খুঁজে পাওয়া যায় তবে আপডেটটি সমস্ত আপডেট হয়ে যায় এবং আপনার অ্যাডআরআপটেটে যা ছিল না তা বাতিল করে দেয়।

এটি বলেছিল, আমার এমন একটি পরিস্থিতি রয়েছে যেখানে আমি কোনও বাহ্যিক পরিষেবা থেকে ডেটা টানছি এবং প্রাথমিক কী দ্বারা বিদ্যমান মানগুলি সন্নিবেশ করিয়ে বা আপডেট করছি (এবং গ্রাহকদের জন্য আমার স্থানীয় ডেটা কেবল পঠনযোগ্য) - AddOrUpdateএখন upd মাসেরও বেশি সময় ধরে উত্পাদন ব্যবহার করা হচ্ছে এখনও কোন সমস্যা।


7
System.Data.Entity.Migration নেমস্পেসে কোড ভিত্তিক মাইগ্রেশন এবং তাদের কনফিগারেশন সম্পর্কিত ক্লাস রয়েছে। মাইগ্রেশন অ-সত্তা অ্যাডঅরআপেটসগুলির জন্য আমাদের আমাদের সংগ্রহস্থলগুলিতে এটি ব্যবহার করা উচিত নয় এমন কোনও কারণ আছে কি?
ম্যাট লেঙ্গেনফিল্ডার

10
অ্যাডআরআপডেট পদ্ধতিটি যত্ন নিন: thedatafarm.com/data-access/…
কলিন

1
এই নিবন্ধটি বর্ণনা কেন AddOrUpdate ব্যবহার করা উচিত নয় michaelgmccarthy.com/2016/08/24/...
Nolmë তথ্যের

11

কল করার সময় যাদুটি ঘটে 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এটি কোনও নতুন সত্তা কিনা তা নির্ধারণ করতে যদি আপনি পরীক্ষা করতে না পারেন তবে লাদিস্লাভ মির্নকার উত্তরটি দেখুন


8

আপনি যদি জানেন যে আপনি একই প্রসঙ্গটি ব্যবহার করছেন এবং কোনও সত্ত্বাকে আলাদা করছেন না, আপনি এটির মতো জেনেরিক সংস্করণ তৈরি করতে পারেন:

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 অবশ্যই কোনও শ্রেণীর ক্ষেত্র হতে পারে, বা পদ্ধতিটি স্থিতিশীল এবং একটি এক্সটেনশন তৈরি করা যেতে পারে তবে এটি মূল বিষয়গুলি।


4

লাডিসালভের উত্তর নিকটে ছিল তবে ইএফ 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);
      }
  }
[....]

অ্যাডআরআপটেটটি সিস্টেম.ডাটা.এন্টিটি.মিজারেশনগুলিতে এক্সটেনশন পদ্ধতি হিসাবে উপস্থিত রয়েছে, সুতরাং আমি যদি আপনি থাকতাম তবে আমি আপনার নিজস্ব পদ্ধতির জন্য একই পদ্ধতির নামটি পুনরায় ব্যবহার করতে এড়াতে চাই।
আফ্রিক্ট করুন

2

আমার মতে এটি বলার অপেক্ষা রাখে না যে সদ্য প্রকাশিত সত্তা ফ্রেমওয়ার্ক কোডের জন্য সত্তা প্রকাশিত এনটিটিগ্রাফফেরেশনগুলির সাথে প্রথমে আপনি গ্রাফের সমস্ত সত্তার রাজ্যগুলির সংজ্ঞা দেওয়ার জন্য কিছু পুনরাবৃত্ত কোড লিখতে নিজেকে বাঁচাতে পারেন। আমি এই পণ্যটির লেখক। এবং আমি এটি গিথুব , কোড-প্রকল্পে প্রকাশ করেছি ( একটি ধাপে ধাপে বিক্ষোভ অন্তর্ভুক্ত এবং একটি নমুনা প্রকল্প ডাউনলোডের জন্য প্রস্তুত) এবং নুগেট

এটা করবে না স্বয়ংক্রিয়ভাবে সত্ত্বা রাজ্যের সেট করতে 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 });
        }
    }

এখানেই শেষ.


2

অন্য দুটি সন্নিবেশ করান

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();
}

আমি এই পদ্ধতির ব্যবহার করেছিলাম এবং পরীক্ষিত (প্রথম বা ডিফল্ট পরে) যদি (ক্যোরি == নাল)
প্যাট্রিক

2

যে কোনও সহ বিদ্যমান সারি পরীক্ষা করুন।

    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();

        }

    }

1

@ লাডিস্লাভ মির্ণা উত্তরের বিকল্প। এটি যদি সত্তা ফ্রেমওয়ার্কের জন্য 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);
    }
}

-1

সংশোধিত

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();
        }

2
দয়া করে অন্য উত্তর পোস্ট করার পরিবর্তে সম্পাদনাটি ব্যবহার করুন
সুরজ রাও
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.