it-swarm.dev

إطار الكيان .Remove () مقابل .DeleteObject ()

يمكنك إزالة عنصر من قاعدة بيانات باستخدام EF باستخدام الطريقتين التاليتين.

الأول على EntityCollection والثاني على ObjectContext.

متى ينبغي استخدام كل منها؟

هل يفضل واحد على الآخر؟

Remove() تُرجع bool و DeleteObject() تُرجع void.

137
Sam Leach

ليس صحيحًا عمومًا أنه يمكنك "إزالة عنصر من قاعدة بيانات" بكلتا الطريقتين. أن نكون دقيقين مثل ذلك:

  • ObjectContext.DeleteObject(entity) علامات الكيان كـ Deleted في السياق. (من EntityState هو Deleted بعد ذلك.) إذا قمت بالاتصال بـ SaveChanges بعد ذلك ، ترسل EF عبارة SQL DELETE إلى قاعدة البيانات. إذا لم تنتهك أي قيود مرجعية في قاعدة البيانات ، فسيتم حذف الكيان ، وإلا سيتم طرح استثناء.

  • EntityCollection.Remove(childEntity) علامات العلاقة بين الأصل و childEntity كـ Deleted. إذا تم حذف childEntity نفسه من قاعدة البيانات وما يحدث بالضبط عند الاتصال SaveChanges ، فهذا يتوقف على نوع العلاقة بين الاثنين:

    • إذا كانت العلاقة اختياري ، أي أن المفتاح الخارجي الذي يشير من الطفل إلى الأصل في قاعدة البيانات يسمح بقيم NULL ، سيتم تعيين هذا الأجنبي على قيمة فارغة وإذا قمت بالاتصال بـ SaveChanges هذه القيمة NULL لـ childEntity إلى قاعدة البيانات (أي يتم إزالة العلاقة بين الاثنين). يحدث هذا مع عبارة SQL UPDATE. لا يوجد بيان DELETE.

    • إذا كانت العلاقة مطلوبة (لا تسمح FK بقيم NULL) والعلاقة لا تحدد (مما يعني أن المفتاح الخارجي ليس جزءًا من المفتاح الأساسي (المركب) للطفل) لديك إما لإضافة الطفل إلى أحد الوالدين أو عليك حذف الطفل بشكل صريح (مع DeleteObject بعد ذلك). إذا لم تقم بأي من هذه القيود ، فقد تم انتهاك قيد مرجعي وسوف تقوم EF باستثناء استثناء عند الاتصال بـ SaveChanges - سيء السمعة " لا يمكن تغيير العلاقة لأن واحدة أو أكثر من خصائص المفتاح الخارجي هي غير قابل للإلغاء " استثناء أو ما شابه.

    • إذا كانت العلاقة تحدد (بالضرورة مطلوبة ، إذن لأن أي جزء من المفتاح الأساسي لا يمكن أن يكون NULL) ستقوم EF بوضع علامة على childEntity كـ Deleted أيضًا. إذا قمت بالاتصال بـ SaveChanges ، فسيتم إرسال عبارة SQL DELETE إلى قاعدة البيانات. إذا لم تنتهك أي قيود مرجعية أخرى في قاعدة البيانات ، فسيتم حذف الكيان ، وإلا سيتم طرح استثناء.

إنني مرتبك بعض الشيء بشأن قسم ملاحظات على صفحة MSDN لقد قمت بالربط لأنك تقول: "إذا كانت العلاقة بها قيد تكامل مرجعي ، فإن استدعاء الأسلوب" إزالة "على كائن تابع يمثل كلا العلاقة والكائن التابع للحذف. ". هذا يبدو غير دقيق أو حتى خاطئ بالنسبة لي لأن الحالات الثلاث المذكورة أعلاه لها "قيود السلامة المرجعية" ولكن فقط في الحالة الأخيرة تم حذف الطفل في الواقع. (ما لم تكن تعني "كائن تابع" كائنًا يشارك في علاقة تعريفية والتي ستكون مصطلحات غير معتادة.)

269
Slauma

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

ObjectContext.DeleteObject (الكيان) علامات الكيان كما تم حذفه في السياق. (إنه يتم حذف EntityState بعد ذلك.) إذا اتصلت بـ SaveChanges بعد ذلك ، ترسل EF عبارة DELETE SQL إلى قاعدة البيانات. إذا لم تنتهك أي قيود مرجعية في قاعدة البيانات ، فسيتم حذف الكيان ، وإلا سيتم طرح استثناء.

EntityCollection.Remove (childEntity) علامات العلاقة بين الوالد و childEntity على أنها محذوفة. إذا تم حذف childEntity نفسه من قاعدة البيانات وما يحدث بالضبط عند استدعاء SaveChanges يعتمد على نوع العلاقة بين الاثنين:

الشيء الجدير بالذكر هو أن إعداد .State = EntityState.Deletedلا يؤدي إلى التغيير الذي تم اكتشافه تلقائيًا. ( أرشيف )

13
Matas Vaitkevicius