ما هي الطريقة الصحيحة للتعامل مع كيانات التتبع الذاتية غير المتقاعدين؟
-
21-09-2019 - |
سؤال
كيانات تتبع الذات. رائع.
إلا عندما تفعل شيئًا مثل
return Db.Users;
لا تتتبع أي من الكيانات ذاتية التغذية الذاتية (حتى يتم إلغاء التخلص منها).
بخير. لذلك علينا أن ندرك أن هناك احتمال أن يكون كيان عودة إلينا قد تم تمكين التتبع.
ماذا الآن؟؟؟
الأشياء التي جربتها
لجسم الطريقة المحددة:
using (var db = new Database())
{
if (update.ChangeTracker.ChangeTrackingEnabled)
db.Configurations.ApplyChanges(update);
else
FigureItOut(update, db);
db.SaveChanges();
update.AcceptChanges();
}
التطبيقات التالية من FigureItOut
كل شيء يفشل:
db.Configurations.Attach(update);
db.DetectChanges();
ولا
db.Configurations.Attach(update);
db.Configurations.ApplyCurrentValues(update);
ولا
db.Configurations.Attach(update);
db.Configurations.ApplyOriginalValues(update);
ولا
db.Configurations.Attach(update);
db.Configurations.ApplyChanges(update
ولا عن أي شيء آخر يمكنني تحديده لرميه ، بخلاف
- الحصول على الكيان الأصلي من قاعدة البيانات
- مقارنة كل خاصية باليد
- تحديث الخصائص حسب الحاجة
ما ، بالضبط ، هل من المفترض أن أفعل مع الكيانات الذاتية التي لا تتتبع نفسها ؟؟
تحديث صغير:
وضع علامة على الكيان بشكل أعمى كأعمال معدلة ، ولكن هذا يبدو رائحته بعض الشيء. هل هو أفضل ما يمكننا القيام به في هذه الحالة؟
المحلول
السيناريو 1
فيما يلي بعض الممارسات الموصى بها لمتابعة. عندما تستخدم STE في سيناريو WCF ، يجب عليك الاعتماد على متتبع التغيير الذي ينفذه Ste على جانب الخادم الذي تقوم به ما يلي.
db.Users.ApplyChanges(user);
db.SaveChanges();
السيناريو 2 ولكن إذا كنت على الخادم ، فإن الممارسة الموصى بها هي إنشاء طريقة على الفئة الجزئية لـ ObjectContext تسمى EnableChangetracking. ستستفسر الطريقة عن الكيانات الموجودة في حالة لم تتغير والتي تنفذ iobjectwithchangetracker وتشغيل تتبع التغيير حتى لا يكون هناك شيء من هذا القبيل
user = db.users.first(u => u.userid == 1);
db.EnableChangeTracking();
حاول الآن حفظ كيان المستخدم من سياق مختلف تم استرداده من الأصل
db2.users.ApplyChanges(user);
db2.SaveChanges();
السيناريو 3 إذا كنت على جانب الخادم متصلاً بنفس سياق الكائن الذي استرجعت منه كيان المستخدم من ذلك ، فأنت تستخدم كائن POCO بسيطًا مثل أدناه
user = db.users.first(u => u.userid == 1);
user.LastName = "XYZ";
db.DetectChanges(); //no need for it cuz Savechanges implicitly calls this.
db.SaveChanges();
السيناريو 4 إذا تم استرداد كيان المستخدم من سياق مختلف ، فسيستخدمه السياق الذي استخدمه للحفظ ، فإليك خيارًا آخر حيث تضع علامة على الكيان على أنه معدل وعدم الاهتمام بما تم تعديله.
user = db.users.first(u => u.userid == 1);
var db2 = new ObjectContext();
user.LastName = "XYZ";
db2.Users.Attach(user);
// i prefer this option..
db2.ObjectStateManager.ChangeObjectState(user,EntityState.Modified);
db2.SaveChanges(); // updates all columns
السيناريو 5 إذا تم استرداد كيان المستخدم من سياق مختلف ، فسيستخدمه السياق الذي استخدمه لحفظه ، ثم هنا خيار آخر حيث تقوم باسترداد الكيان الأصلي.
user = db.users.first(u => u.userid == 1);
user.lastName ="XYZ";
var db2 = new ObjectContext();
db2.Users.First(u => u.userid == user.userid);
db2.users.ApplyCurrentValues(user);
db2.SaveChanges();
فيما يلي منشور مدونة يصف سيناريوهات قليلة.http://weblogs.asp.net/zeeshanhirani/archive/2010/03/30/modification-self-tracking-entity-on-the-server.aspx
أغطي على نطاق واسع هذه المفاهيم في كتاب وصفات إطار الكيان 4.0 مع الكثير من السيناريوهات ..