সত্তা ফ্রেমওয়ার্ক 5 একটি রেকর্ড আপডেট করা


870

আমি একটি এএসপি.নেট এমভিসি 3 পরিবেশে সত্ত্বা ফ্রেমওয়ার্ক 5 এর মধ্যে রেকর্ড সম্পাদনা / আপডেট করার বিভিন্ন পদ্ধতি অনুসন্ধান করে চলেছি, তবে এখনও পর্যন্ত তাদের কোনওটিই আমার প্রয়োজনীয় সমস্ত বাক্সগুলিতে টিক চিহ্ন দেয় না। আমি ব্যাখ্যা করব কেন।

আমি তিনটি পদ্ধতি খুঁজে পেয়েছি যার সাথে আমি ভাল ও কুফলগুলি উল্লেখ করব:

পদ্ধতি 1 - আসল রেকর্ডটি লোড করুন, প্রতিটি সম্পত্তি আপডেট করুন

var original = db.Users.Find(updatedUser.UserId);

if (original != null)
{
    original.BusinessEntityId = updatedUser.BusinessEntityId;
    original.Email = updatedUser.Email;
    original.EmployeeId = updatedUser.EmployeeId;
    original.Forename = updatedUser.Forename;
    original.Surname = updatedUser.Surname;
    original.Telephone = updatedUser.Telephone;
    original.Title = updatedUser.Title;
    original.Fax = updatedUser.Fax;
    original.ASPNetUserId = updatedUser.ASPNetUserId;
    db.SaveChanges();
}    

পেশাদাররা

  • কোন বৈশিষ্ট্য পরিবর্তন তা নির্দিষ্ট করতে পারে
  • দর্শনগুলির প্রতিটি সম্পত্তি থাকা দরকার নেই

কনস

  • মূল লোড করতে ডাটাবেসে 2 এক্স ক্যোয়ারী এটি আপডেট করুন

পদ্ধতি 2 - আসল রেকর্ডটি লোড করুন, পরিবর্তিত মান সেট করুন

var original = db.Users.Find(updatedUser.UserId);

if (original != null)
{
    db.Entry(original).CurrentValues.SetValues(updatedUser);
    db.SaveChanges();
}

পেশাদাররা

  • কেবলমাত্র পরিবর্তিত বৈশিষ্ট্যগুলি ডাটাবেসে প্রেরণ করা হয়

কনস

  • দর্শনে প্রতিটি সম্পত্তি থাকা দরকার
  • মূল লোড করতে ডাটাবেসে 2 এক্স ক্যোয়ারী এটি আপডেট করুন

পদ্ধতি 3 - আপডেট রেকর্ড সংযুক্ত করুন এবং এন্টিস্টেস্ট.মোডাইফাইডে রাষ্ট্র সেট করুন

db.Users.Attach(updatedUser);
db.Entry(updatedUser).State = EntityState.Modified;
db.SaveChanges();

পেশাদাররা

  • আপডেট করার জন্য ডাটাবেসে 1 এক্স ক্যোয়ারী

কনস

  • কোন বৈশিষ্ট্য পরিবর্তন তা নির্দিষ্ট করে বলা যায় না
  • দর্শনে প্রতিটি সম্পত্তি থাকতে হবে

প্রশ্ন

আপনাদের কাছে আমার প্রশ্ন; আমি এই সেট লক্ষ্য অর্জন করতে পারে যে একটি পরিষ্কার উপায় আছে?

  • কোন বৈশিষ্ট্য পরিবর্তন তা নির্দিষ্ট করতে পারে
  • ভিউগুলিতে প্রতিটি সম্পত্তি (যেমন পাসওয়ার্ড) থাকা দরকার নেই
  • আপডেট করার জন্য ডাটাবেসে 1 এক্স ক্যোয়ারী

আমি বুঝতে পারি এটি উল্লেখ করা বেশ ছোটখাটো জিনিস তবে আমি এর সহজ সমাধানটি অনুপস্থিত হতে পারি। যদি পদ্ধতি না হয় তবে একটিটি বিজয়ী হবে ;-)


13
ভিউমোডেলস এবং একটি ভাল ম্যাপিং ইঞ্জিন ব্যবহার করবেন? আপনি আপনার ভিউ জনিত করতে (এবং তারপরে আপডেট করার জন্য) কেবলমাত্র "আপডেট করার জন্য বৈশিষ্ট্যগুলি" পান। আপডেট করার জন্য এখনও দুটি প্রশ্ন থাকবে (মূল এটি আপডেট করুন) তবে আমি এটিকে "কন" বলব না। যদি এটি আপনার একমাত্র পারফরম্যান্স সমস্যা হয় তবে আপনি একজন সুখী মানুষ;)
রাফাল আলথাস

ধন্যবাদ @ রাফালআলথাস, খুব বৈধ পয়েন্ট। আমি এটি করতে পারলাম, তবে আমাকে বেশ কয়েকটি টেবিলের জন্য সিআরইউডি অপারেশন তৈরি করতে হবে তাই আমি এমন একটি পদ্ধতি খুঁজছি যা প্রতিটি মডেলের জন্য এন -1 ভিউমোডেল তৈরি করতে আমাকে রক্ষা করতে সরাসরি মডেলটির সাথে কাজ করতে পারে।
স্টকড আউট

3
ঠিক আছে, আমার বর্তমান প্রকল্পে (অনেক সত্তাও) আমরা মডেলগুলিতে কাজ শুরু করে ভেবেছিলাম ভিউমোডেলসের সাথে কাজ করে সময় নষ্ট করব। আমরা এখন ভিউমোডেলগুলিতে যাচ্ছি, এবং শুরুতে (তুচ্ছ নয়) অবকাঠামোগত কাজগুলি, এটি এখন পর্যন্ত বহালূর, সুদূর, আরও পরিষ্কার এবং সহজ বজায় রাখা সহজ। এবং আরও সুরক্ষিত (দূষিত "লুকানো ক্ষেত্রগুলি" বা এই জাতীয় জিনিসগুলি সম্পর্কে ভয় পাওয়ার দরকার নেই)
রাফাল আলথাস

1
এবং আপনার ড্রপডাউনলিস্টগুলি জনপ্রিয় করার জন্য ভিউব্যাগগুলি নেই (আমাদের প্রায় সমস্ত সিআরইউ (ডি) দর্শন নিয়ে আমাদের কমপক্ষে একটি ড্রপডাউনলিস্ট আছে ...)
রাফাল আলথাস

আমি মনে করি আপনি ঠিক বলেছেন, ভিউমোডেলগুলি উপেক্ষা করার চেষ্টা করার জন্য আমার খারাপ। হ্যাঁ, ভিউব্যাগটি মাঝে মাঝে কিছুটা নোংরা মনে হয়। আমি ডিনো এস্পোসিতোর ব্লগ অনুসারে সাধারণত আরও এক ধাপ এগিয়ে যাই এবং ইনপুটমডেলসও তৈরি করি, একটি ট্যাড বেল্ট এবং ধনুর্বন্ধনী তবে এটি বেশ কার্যকরভাবে কাজ করে। মাত্র প্রতিটি মডেল হিসাবে 2 অতিরিক্ত মডেল
দোহ

উত্তর:


681

আপনি খুঁজছেন:

db.Users.Attach(updatedUser);
var entry = db.Entry(updatedUser);
entry.Property(e => e.Email).IsModified = true;
// other changed properties
db.SaveChanges();

59
হাই @ লাডিস্লাভ মির্নকা, আমি যদি সমস্ত সম্পত্তি একবারে আপডেট করতে চাই তবে আমি কি নীচের কোডটি ব্যবহার করতে পারি? db.Departments.Attach (বিভাগ); db.Entry (বিভাগ) .State = EntityState.Modified; db.SaveChanges ();
ফয়েজুল করিম

23
@ ফয়েসাল: হ্যাঁ আপনি পারবেন।
লাদিস্লাভ মিঙ্কা

5
এই পদ্ধতির সমস্যাগুলির মধ্যে একটি হ'ল আপনি db.Entry () কে উপহাস করতে পারবেন না, এটি একটি মারাত্মক পিআইটিএ। EF এর কাছে অন্য কোথাও যথেষ্ট উপহাসের গল্প রয়েছে - এটি বেশ বিরক্তিকর যে (যতদূর আমি বলতে পারি) তাদের এখানে নেই।
কেন স্মিথ

23
@ ফয়েজাল করণ প্রসঙ্গ.এন্ট্রি (সত্তা)। স্টেট = সত্তা স্ট্যাট.এই সংযুক্তি করার জন্য এককভাবে মোডিফাই করা যথেষ্ট নয়। এটি স্বয়ংক্রিয়ভাবে এর পরিবর্তিত হিসাবে সংযুক্ত হবে ...
হ্যালো ওয়ার্ল্ড

4
@ Sandman4, এর অর্থ হল যে অন্যান্য সমস্ত সম্পত্তি সেখানে থাকা উচিত এবং বর্তমান মানটিতে সেট করা দরকার। কিছু অ্যাপ্লিকেশন ডিজাইনে, এটি সম্ভাব্য নয়।
ড্যান

176

আমি সত্যিই গৃহীত উত্তর পছন্দ করি। আমি বিশ্বাস করি এটির কাছে যাওয়ার আরও একটি উপায় আছে। ধরা যাক আপনার কাছে এমন একটি সম্পত্তিগুলির খুব সংক্ষিপ্ত তালিকা রয়েছে যা আপনি কখনও কোনও ভিউতে অন্তর্ভুক্ত করতে চান না, সুতরাং সত্তাটি আপডেট করার সময় সেগুলি বাদ দেওয়া হবে। ধরা যাক যে এই দুটি ক্ষেত্র হ'ল পাসওয়ার্ড এবং এসএসএন।

db.Users.Attach(updatedUser);

var entry = db.Entry(updatedUser);
entry.State = EntityState.Modified;

entry.Property(e => e.Password).IsModified = false;
entry.Property(e => e.SSN).IsModified = false;   

db.SaveChanges();   

এই উদাহরণটি আপনাকে ব্যবহারকারীর টেবিলটিতে এবং আপনার দৃশ্যে একটি নতুন ক্ষেত্র যুক্ত করার পরে আপনার ব্যবসায়িক যুক্তিটি মূলত একা ছাড়তে দেয়।


তবুও আমি এসএসএন সম্পত্তির জন্য কোনও মান নির্দিষ্ট না করলে আমি একটি ত্রুটি পেয়ে যাব, যদিও আমি ইসমোডিফাইডকে মিথ্যা হিসাবে সেট করেছি যদিও এটি এখনও মডেল বিধির বিপরীতে সম্পত্তিটিকে বৈধতা দেয়। সুতরাং সম্পত্তিটি যদি নাল হিসাবে চিহ্নিত হয় তবে এটি ব্যর্থ হবে যদি আমি নাল থেকে আলাদা কোনও মান সেট না করি।
রোল্যান্ডোসিসি

আপনি কোনও ত্রুটি পাবেন না কারণ সেগুলি ক্ষেত্রগুলি আপনার ফর্মে থাকবে না। আপনি অবশ্যই ক্ষেত্রগুলি ছেড়ে যান যা আপনি অবশ্যই আপডেট করবেন না, এটি সংযুক্ত করে ফর্মটি পাস করে ব্যবহার করে ডাটাবেস থেকে প্রবেশটি ধরুন এবং এন্ট্রিটি বলুন যে fields ক্ষেত্রগুলি সংশোধন হচ্ছে না। মডেল বৈধতা মডেলস্টেটে নিয়ন্ত্রণ করা হয়, প্রসঙ্গে নয়। এই উদাহরণটি একটি বিদ্যমান ব্যবহারকারীকে উল্লেখ করছে, অতএব "আপডেটডউসার"। আপনার এসএসএন যদি প্রয়োজনীয় ক্ষেত্র হয় তবে এটি প্রথম তৈরি হওয়ার সময় সেখানে উপস্থিত হত।
এসএমডি

4
আমি যদি সঠিকভাবে বুঝতে পারি তবে "আপডেটডুজার" একটি ফার্স্টঅরডিফল্ট () বা অনুরূপ দ্বারা ইতিমধ্যে পপুলেটেড একটি সামগ্রীর উদাহরণ, তাই আমি কেবলমাত্র পরিবর্তিত বৈশিষ্ট্যগুলি আপডেট করছি এবং অন্যকে আইএসএমডিফায়েড = মিথ্যাতে সেট করছি। এটি কাজ করে। তবে, আমি যা করার চেষ্টা করছি তা হ'ল কোনও অবজেক্টটিকে প্রথমে পপুলেশন ছাড়াই আপডেট করা, কোনও আপডেট ফার্স্টআরডিফল্ট () আপডেট না করে। আমি যখন সমস্ত প্রয়োজনীয় ক্ষেত্রের জন্য কোনও মান নির্দিষ্ট না করি, ততক্ষণে আমি কোনও ত্রুটি পেয়েছি, এমনকি আমি এই বৈশিষ্ট্যগুলিতে ISModified = মিথ্যা সেট করেছি। এন্ট্রি.প্রপার্টি (e => e.columnA) .আইএসএমডিফায়েড = মিথ্যা; এই লাইন ছাড়া কলামা ব্যর্থ হবে fail
রোল্যান্ডোসিসি

আপনি যা বর্ণনা করছেন তা একটি নতুন সত্তা তৈরি করছে। এটি শুধুমাত্র আপডেট করার ক্ষেত্রে প্রযোজ্য।
smd

1
RolandoCC, put db.Configration.ValidateOnSaveEn اهل = মিথ্যা; আগে db.SaveChanges ();
উইলকি

28
foreach(PropertyInfo propertyInfo in original.GetType().GetProperties()) {
    if (propertyInfo.GetValue(updatedUser, null) == null)
        propertyInfo.SetValue(updatedUser, propertyInfo.GetValue(original, null), null);
}
db.Entry(original).CurrentValues.SetValues(updatedUser);
db.SaveChanges();

এটিকে সত্যিই দুর্দান্ত সমাধান বলে মনে হচ্ছে - কোনও গণ্ডগোল বা গোলযোগ নেই; আপনাকে ম্যানুয়ালি বৈশিষ্ট্য নির্দিষ্ট করতে হবে না এবং এটি ওপিএসের সমস্ত গুলি বিবেচনা করে - এটির বেশি ভোট না পাওয়ার কোনও কারণ আছে কি?
নিশাচর

যদিও এটি না। এটিতে সবচেয়ে বড় একটি "কনস" রয়েছে, এটি ডাটাবেসে একাধিক হিট। আপনাকে এখনও এই উত্তরটির সাথে মূলটি লোড করতে হবে।
smd

1
@ এসএমডি আপনি কেন বলেন যে এটি একাধিকবার ডাটাবেসটিকে হিট করে? আমি দেখতে পাচ্ছি না যে সেটভ্যালু () ব্যবহার না করা থাকলে এর প্রভাব রয়েছে তবে এটি সত্য বলে মনে হয় না।
সংসদ

@ পার্লামেন্ট আমার মনে হয় আমি যখন এটি লিখেছিলাম তখন অবশ্যই আমি ঘুমিয়ে ছিলাম। দুঃক্ষিত। আসল সমস্যাটি হ'ল নাল মানকে ওভাররাইড করে। আপডেট হওয়া ব্যবহারকারীর যদি আর কোনও বিষয়ে রেফারেন্স না থাকে, আপনি যদি এটি সাফ করতে চেয়েছিলেন তবে এটি মূল মান দিয়ে প্রতিস্থাপন করা ঠিক হবে না।
এসএমডি

22

আমি আমার সংগ্রহস্থল বেস শ্রেণিতে একটি অতিরিক্ত আপডেট পদ্ধতি যুক্ত করেছি যা স্ক্যাফোোল্ডিংয়ের দ্বারা উত্পন্ন আপডেট পদ্ধতির অনুরূপ। সম্পূর্ণ অবজেক্টটিকে "সংশোধিত" এ সেট করার পরিবর্তে এটি পৃথক বৈশিষ্ট্যের একটি সেট সেট করে। (টি একটি শ্রেণীর জেনেরিক প্যারামিটার))

public void Update(T obj, params Expression<Func<T, object>>[] propertiesToUpdate)
{
    Context.Set<T>().Attach(obj);

    foreach (var p in propertiesToUpdate)
    {
        Context.Entry(obj).Property(p).IsModified = true;
    }
}

এবং তারপরে কল করা, উদাহরণস্বরূপ:

public void UpdatePasswordAndEmail(long userId, string password, string email)
{
    var user = new User {UserId = userId, Password = password, Email = email};

    Update(user, u => u.Password, u => u.Email);

    Save();
}

আমি ডাটাবেসে একটি ট্রিপ পছন্দ করি। বৈশিষ্ট্যের সেটগুলি পুনরাবৃত্তি করা এড়াতে, যদিও ভিউ মডেলগুলির সাথে এটি করা ভাল। আমি এখনও এটি করিনি কারণ আমি জানি না কীভাবে আমার ডোমেন প্রকল্পে আমার ভিউ মডেল ভ্যালিডিটারগুলিতে বৈধতা বার্তা আনতে হবে।


আহা ... ভিউ মডেলগুলির জন্য পৃথক প্রকল্প এবং ভিউ মডেলগুলির সাথে কাজ করে এমন সংগ্রহস্থলগুলির জন্য পৃথক প্রকল্প।
ইয়ান ওয়ারবার্টন

11
public interface IRepository
{
    void Update<T>(T obj, params Expression<Func<T, object>>[] propertiesToUpdate) where T : class;
}

public class Repository : DbContext, IRepository
{
    public void Update<T>(T obj, params Expression<Func<T, object>>[] propertiesToUpdate) where T : class
    {
        Set<T>().Attach(obj);
        propertiesToUpdate.ToList().ForEach(p => Entry(obj).Property(p).IsModified = true);
        SaveChanges();
    }
}

কেন শুধু ডিবি কনটেক্সট নয় ttএটাচ (আপত্তি); DbContext.Entry (obj) .State = EntityState.Modified;
নেলসন্ট্রুরণ

এটি setআপডেট স্টেটমেন্টের অংশটি নিয়ন্ত্রণ করে ।
তানভীর বদর

4

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


3

আপনার ব্যবহারের উপর নির্ভর করে উপরের সমস্ত সমাধান প্রযোজ্য। যদিও আমি সাধারণত এটি করি:

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

ক্লায়েন্টের পক্ষের দৃশ্যের জন্য আপনার কাছে কয়েকটি বিকল্প রয়েছে

  1. দর্শন মডেল ব্যবহার করুন। মডেলগুলির একটি সম্পত্তি আপডেটস্ট্যাটাস থাকতে হবে (অযুহিত-সন্নিবেশিত-আপডেট-মোছা)। ব্যবহারকারীর ক্রিয়া (সন্নিবেশ-আপডেট-মোছা) এর উপর নির্ভর করে এই কলামটিতে সঠিক মান সেট করা ক্লায়েন্টের দায়িত্ব। সার্ভার হয় হয় মূল মানগুলির জন্য ডিবিকে জিজ্ঞাসা করতে পারে বা ক্লায়েন্টকে পরিবর্তিত সারিগুলির সাথে সার্ভারে মূল মানগুলি প্রেরণ করতে হবে। সার্ভারের মূল মানগুলি সংযুক্ত করা উচিত এবং নতুন মানগুলি কীভাবে পরিচালনা করতে হবে তা ঠিক করার জন্য প্রতিটি সারিতে আপডেটস্ট্যাটাস কলামটি ব্যবহার করা উচিত। এই দৃশ্যে আমি সর্বদা আশাবাদী সমঝোতা ব্যবহার করি। এটি কেবল সন্নিবেশ - আপডেট - বিবৃতি মুছে ফেলবে এবং কোনও বাছাই করে না, তবে গ্রাফটি চালনা করতে এবং সত্তাগুলি আপডেট করতে কিছু চতুর কোডের প্রয়োজন হতে পারে (আপনার দৃশ্যের উপর নির্ভর করে - অ্যাপ্লিকেশন)। একটি ম্যাপার সাহায্য করতে পারে তবে সিআরইউডি যুক্তি পরিচালনা করে না

  2. Breeze.js এর মতো একটি লাইব্রেরি ব্যবহার করুন যা এই জটিলতাটির বেশিরভাগটি লুকিয়ে রাখে (1 হিসাবে বর্ণিত) এবং এটি আপনার ব্যবহারের ক্ষেত্রে ফিট করার চেষ্টা করুন।

আশা করি এটা সাহায্য করবে

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