إطار كيان:هل هناك طريقة للتحقق مما إذا كان السياق يحتوي على كائن؟

StackOverflow https://stackoverflow.com/questions/675625

سؤال

الموقف:لا يمكن تعيين الكائن الموجود في الجلسة من سياق سابق كأصل لكائن آخر نظرًا لوجود كائن آخر في سياق جديد.

لنفترض أن لدي مستخدمًا في الجلسة قمت باستعادته من السياق.يتم الآن إعادة تحميل الصفحة، وتم استبعاد هذا السياق وإنشاء سياق جديد.

someUser = context.First(user => user.id == id);
Session["SomeUser"] = someUser
...
context.Dispose();

إعادة تحميل الصفحة

userAddress = new UserAddress();
userAddress.User = (User)Session["SomeUser"]; //BOOM NOT IN SAME CONTEXT

ما أود القيام به هو:

if(!context.SomeUsers.Contains((User)Session["SomeUSer"]) //Only check context NOT DATABASE
{
   //Reload from database
   //Set user in session to new object
}

الفكرة هي أنه إذا كان الكائن الموجود في الجلسة لا ينتمي إلى السياق الحالي، فأعد تحميله من قاعدة البيانات بحيث يصبح الآن "مملوكًا" لنفس السياق مثل أي كائن آخر في السياق الحالي.(أنا أستخدم سياقًا لكل طلب)

تحديث

لذلك قمت بذلك مؤقتًا حتى أتمكن من الحصول على فكرة أفضل عن كيفية إصلاح ذلك:

Int32 sessionUser = sessionUser .UserID;
var userCheck = EntityContext.Context.ChatUsers.First(item => item.UserID == returnValueID);
if (userCheck != sessionUser)
{
   sessionUser = userCheck;
}

الفكرة هي معرفة ما إذا كان الكائن الموجود في الجلسة (sessionUser) هو نفس الكائن "الموجود" في السياق.الآن إذا يعمل بشكل جيد.في المرة الأولى التي يتم فيها إنشاء السياق، يجب أن يصل ذلك إلى قاعدة البيانات ويلتقط المستخدم.بمجرد المقارنة، من الواضح أنهما ليسا متماثلين وأن sesionUser هو الآن المستخدم في السياق.في المرة القادمة التي يتم فيها تحديد ذلك، فإن sessionUser وuserToCheck متماثلان.

لا تزال المشكلة هي:

var userCheck = EntityContext.Context.ChatUsers.First(item => item.UserID == returnValueID);

دائما يضرب قاعدة البيانات.هذا ليس حلا جيدا.

المزيد من التحديث

ميه قد يكون هذا هو الجواب بعد كل شيء.لقد نسيت هذه القاعدة:

x هي خاصية من النوع ObjectQuery.عند تنفيذ ObjectQuery، فإنه سوف تصل دائما إلى متجر الدعم.هذا ما يفعلونه.إذا كنت لا تريد لتنفيذ استعلام قاعدة بيانات، ثم لا تستخدم ObjectQuery.

هل كانت مفيدة؟

المحلول

حسنا حصلت عليه.

ChatUser userCheck = (ChatUser)EntityContext.Context.GetObjectByKey(returnValue.EntityKey);

if(userCheck != returnValue)
{
   sessionUser = userCheck;
}

طريقة GetObjectByKey والتي توصف بأنها:

يحاول GetObjectByKey استرداد ملف الكائن الذي يحتوي على المحدد EntityKey من أوبجيكتستيتماناجر.إذا لم يتم تحميل الكائن حاليا في سياق الكائن ، يكون الاستعلام تم إعدامه في محاولة لإعادة كائن من مصدر البيانات.

لقد أجريت بعض الاختبارات وهي تفعل ما تقوله.في المرة الأولى من خلال (تم إنشاء السياق عند الطلب) فإنه يصل إلى قاعدة البيانات ويتحقق من هذا الكائن مقابل ما هو موجود في الجلسة.الاثنان ليسا متماثلين، لذا فهو يضبط sessionUser على الكائن الجديد، وبالتالي يوجد الآن sessionUser في السياق وفي الجلسة.في المرة القادمة، تقوم طريقة GetObjectByKey بفحص السياق فقط (حيث لم يُظهر Profiler أي تفاعل مع قاعدة البيانات).ياي.

نصائح أخرى

لماذا لا تتحقق فقط من معرف المستخدم؟

context.Users.Any(user => user.Id = ((User)session["SomeUser"]).Id)

أو يمكنك فقط فصل كائن المستخدم عن السياق القديم وإرفاقه بالسياق الجديد باستخدام context.Attach().

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top