كيف تقوم بإدخال أو تحديث العديد من الجداول في إطار كيان .NET

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

سؤال

يبدو أن هذا يجب أن يكون واضحا تماما ولكن شيء عن إطار الكيان يربكني ولا يمكنني الحصول على هذا للعمل.

بكل بساطة، لدي ثلاثة جداول حيث تكون قيم المعرف هي الأعمدة الهوية: فئات المستخدمين (Userid، اسم المستخدم) الفئات (CESPUTYID، CYSTALNAME) قابلة للإمكانية (معرف المستخدم، فئة سيد) مركب.

في مصمم الكيانات (هذا هو .NET 4.0)، عندما استيراد هذه الجداول، كما هو متوقع لا يظهر جدول الانضمام ولكن المستخدمين والفئات تظهر علاقة. الرمز التالي:

var _context = new MyContext();
var myUser = new User();
myUser.UserName = "joe";

var myCategory = new Category();
myCategory.CategoryName = "friends";

_context.Users.AddObject(myUser);  
myUser.Categories.Add(myCategory);

var saved = _context.SaveChanges();

إرجاع خطأ (على الرغم من أنه تمت إضافة أي شيء إلى قاعدة البيانات):

An item with the same key has already been added.

إذا أضفت ما يلي قبل حفظ:

_context.Categories.AddObject(myCategory);
myCategory.Users.Add(myUser);

أحصل على نفس الخطأ ولا يتم حفظ أي شيء في DB. إذا قمت بحفظ كائن Myuser و MyCategory قبل محاولة ربطهم، فسيحفظ كلاهما، لكن الحفظ الثاني يلقي خطأ، مع عدم إضافة أي شيء إلى جدول الانضمام:

Cannot insert the value NULL into column 'UserId', table '...dbo.JoinTable'; column does not  allow nulls. INSERT fails. The statement has been terminated.

أنا أفهم بوضوح في فهم عدد العلاقات العديدة المدرجة. ماذا ينقصني؟

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

المحلول

تحتاج إلى الاتصال Savechanges () بعد إضافة كيانات المستخدم والفئات إلى قاعدة البيانات، ثم قم بتعيين جمعيتك بينهما.

ومع ذلك، فإن المشكلة الحقيقية هنا هي الاستثناء الثاني الذي أدرجته. إذا نظرت إلى SQLProfiler أو Profiler ADO.NET داخل المصحح، فسترى أنه خلال دعوة Savechanges الثانية، يبدو أنه شيء من هذا القبيل:

insert [dbo].[JoinTable]([UserId]) values (@0) select [CategoryId] from
[dbo].[JoinTable] where @@ROWCOUNT > 0 and [UserId] = @0 and [CategoryId] = scope_identity()

من الواضح أن هذا لن يعمل إذا برمجت الخاص بك بشكل صحيح (PK مركب على كلا الأعمدة).

إذا نظرت إلى متجر EntityModel من خلال المتصفح النموذجي، فهذا يدل على أن عمود الفئة في الداخل قابل للامتصant قد يحتوي بالفعل على StoreGeneratedCattern على الهوية أثناء تعيين UserID إلى بلا. لماذا فعلت EF هذا خلال مرحلة الجيل عندما كان PK مركب موجود خارجي. سأقوم بنشر خطأ حول هذا الأمر إلى MS، ولكن في الوقت الذي يمكنك فيه تحرير ملف EDMX / SSDL يدويا بعد جيل لإزالة محدد الهوية. ابحث عن StoreGeneratedPattern = "الهوية" سلسلة تحت علامة خاصية علامة EntityType لبلدتك القابلة لإزالتها:

يتغيرون:

<Property Name="CategoryId" Type="int" Nullable="false" StoreGeneratedPattern="Identity" />

ل:

<Property Name="CategoryId" Type="int" Nullable="false" />

ثم عند تشغيل التعليمات البرمجية، ستحصل على استعلام أفضل بكثير (وليس استثناء أكثر!):

insert [dbo].[JoinTable]([UserId], [CategoryId]) values (@0, @1)

نصائح أخرى

الطريقة التي قمت بها هذا هو إنشاء كيان فئة صالحا لأول مرة مع مفتاح الكيان.

Category myCategory = _context.Categories.First(i => i.CategoryID == categoryIDToUse);

أو يمكنك محاولة إنشاء الكيان كعبز لحفظ الضرب إلى DB:

Category myCategory = new Category{CategoryID = categoryIDToUse };

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

myUser.Categories.Add(myCategory);

اتصل Savechanges (). وقد عمل ذلك بالنسبة لي.

عندما يضاف الوالد الجديد إلى السياق، فإن حالة كائن كل شيء في تغييرات شجرة الكائنات التي تم إضافتها، وبالتالي يحاول EF حفظ جميع هذه الكائنات كرقجل جديد.

احيل هذا الرابط:http://nileshhirapra.blogspot.inourol2/03/entity-framework-insert-operation-with.html.

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