كيف يمكنني ضمان عدم تجاوز Linq إلى Sql أو خرق القيم الافتراضية لـ DB غير القابلة للتلف؟

لدي SQL Server DB مع جدول يحتوي على هذه الحقول:

  1. بت مع القيمة الافتراضية 1 ، NOT NULL .
  2. smalldatetime مع القيمة الافتراضية gettime() ، NOT NULL .
  3. int بدون قيمة افتراضية ، IDENTITY ، NOT NULL .

عندما أقوم بإنشاء Linq إلى SQL لهذا الجدول ، يحدث ما يلي:

  1. لا يتم إعطاء bit معالجة خاصة.
  2. لا يتم إعطاء smalldatetime معاملة خاصة.
  3. تم وضع علامة int على هيئة IsDbGenerated .

هذا يعني أنه عندما أقوم بإجراء عمليات الإدراج باستخدام Linq إلى SQL ، سيحدث ما يلي:

  1. The bit will be sent as 0, overriding the default value. Right?
  2. The smalldatetime will be sent as an uninitialized System.DateTime, producing an error in SQL server since it doesn't fall with the SQL Server smalldatetime range. Right?
  3. The IsDbGenerated int will not be sent; the DB will generate a value which Linq to SQL will then read back.

What changes do I have to make to make this scenario work?

للتلخيص: أريد حقولًا غير قابلة للقيم ذات قيم افتراضية معيّنة من قِبل DB ، لكنني لا أريدها IsDbGenerated إذا كان ذلك يعني أنه لا يمكنني تقديم قيم لها عند إجراء التحديثات أو الإدخالات باستخدام Linq إلى SQL. أنا أيضا لا أريد لهم IsDbGenerated إذا كان ذلك يعني أن لدي اليد لتعديل التعليمات البرمجية التي تم إنشاؤها بواسطة Linq إلى SQL.

EDIT: يبدو أن هذا هو الحد في Linq إلى SQL.

14
مكرر: stackoverflow.com/q/1120858/11683 (لا يصوت على الإغلاق ، كلاهما مفيد على حد سواء).
وأضاف المؤلف GSerg, مصدر

4 إجابة

لا يتم التقاط الفئات التي تم إنشاؤها Linq-To-Sql "القيم الافتراضي القيمة".

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

  • يمكنك كتابة مولد شفرة لإنشاء فئات جزئية للكيانات حيث يمكنك استخراج قيمة القيمة الافتراضية. </لى>
  • بدلاً من ذلك ، قد تقوم شفرة طبقة الأعمال الخاصة بك بتعيين الإعدادات الافتراضية في المنشئين من ملف xml ، وكل ما تحتاج إليه هو الحفاظ على تحديث ملف xml. </لى>
  • بدلاً من إجراء العمل في المنشئات ، يمكنك محاكاة SQL وإضافة القيم الافتراضية عن طريق فحص ChangeSet قبل إرسال التغييرات إلى قاعدة البيانات.

The issue you are having is described at length in CodeProject - Setting Default Values for LINQ Bound Data

5
وأضاف
"على linq بطريقة ما أن تعرف كيف تترجم تلك" - لماذا؟ يمكن أن تسمح فقط بتمرير أي شيء على إنشاء/تحديث ، وقراءتها مرة أخرى بعد ذلك. هذه هي الطريقة التي تعمل بها الحقول IsDbGenerated ، باستثناء حالة القراءة فقط على الجانب Linq.
وأضاف المؤلف bzlm, مصدر
بالتأكيد ، قد تسمح بذلك ، لكنها لا تسمح بذلك. IsDbGenerated هو فقط للأعمدة الأساسية في هذه المرحلة الزمنية. "linq بطريقة ما ..." هو مجرد رأيي لماذا قد يكون هذا هو الحال.
وأضاف المؤلف Robert Paulson, مصدر
يبدو أن IsDbGenerated متاح الآن للأعمدة غير الرئيسية كذلك.
وأضاف المؤلف Make it useful Keep it simple, مصدر

لقد واجهت نفس المشكلة ، bzlm ، وتوصل إلى نفس النتيجة. ببساطة لا توجد طريقة جيدة للحصول على حقول غير nullable مع القيم الافتراضية المعينة من قِبل DB التي تعمل مع Linq To Sql.

العمل حول لقد ذهبت مع إضافة أسلوب SetDefaults() تشبه إلى حد كبير واحد Robert Paulson مرتبط على CodeProject واستدعاءها في مُنشئ افتراضي للفئة الأساسية كيان الجدول الخاص بي. إنه يعمل جيدًا بالنسبة لي ، لأن 95٪ من الوقت ، أقوم بتعيين 0 ، أو سلسلة فارغة ، أو getdate ().

3
وأضاف
نعم نفسه هنا. شكر!
وأضاف المؤلف bzlm, مصدر

This means that when I make inserts using Linq to SQL, the following will happen:

  1. The bit will be sent as 0, overriding the default value. Right? - Correct
  2. The smalldatetime will be sent as an uninitialized System.DateTime, producing an error in SQL server since it doesn't fall with the SQL Server smalldatetime range. Right? - What is sent is DateTime.MinValue
  3. The IsDbGenerated int will not be sent; the DB will generate a value which Linq to SQL will then read back. - If DB generated is set then the value is created by the database, if not then Linq expects the user to set the value.

أفضل رهان هو تعيينهم في مُنشئ الكائن ، أو في الحقول الخاصة ، إذا كنت لا تستخدم الخصائص التلقائية.

2
وأضاف
من الممكن لكن لا يمكنك تغييرها بعد الحقيقة. إذا كنت تريد أن تكون قادرًا على تغييرها ، فعليك إنشاءها في المُنشئ.
وأضاف المؤلف David Basarab, مصدر
لا تستخدم المُنشئ ، فهناك طريقة جزئية خاصة تسمى OnCreate لهذا الغرض. انظر هذا السؤال: stackoverflow.com/questions/82409/&hellip؛
وأضاف المؤلف Sam, مصدر
يبدو كما لو كنت تقول أن القيم الافتراضية على الحقول في قيم SQL Server غير ممكنة للدمج مع Linq To SQL. هل هذا صحيح؟
وأضاف المؤلف bzlm, مصدر
آسف ، أنا لا أفهم. ما هو ممكن؟ وما الذي لا يمكن تغييره بعد أي حقيقة؟ هل من الممكن جعل Linq إلى SQL تنفيذ إدراج ولديك "القيم الافتراضية" المحددة في قاعدة البيانات المستخدمة؟
وأضاف المؤلف bzlm, مصدر
في الواقع ، إنه OnCreated. أجوبة Longhorn213 مربكة جدا ، وهو أيضا قام بتحرير سؤالي الأصلي لعدم وجود سبب على ما يبدو. فقط تجاهله.
وأضاف المؤلف bzlm, مصدر

يمكنك إنشاء ملف آخر من أجل datacontext الخاص بك (فئة جزئية) ثم استخدام أساليب جزئية InsertYOURENTITY و UpdateYOENTENTITY لفحص خصائصك وتعيين القيم الصحيحة. استدعاء ExecuteDynamicInsert أو ExecuteDynamicUpdate بعد التعليمة البرمجية الخاصة بك وتعيين.

0
وأضاف
في الواقع ، الطريقة الموصى بها للقيام بذلك في BLL هي تنفيذ الأسلوب الجزئي OnCreated() للكيان ، وليس الطريقة التي تقترحها. ومع ذلك ، لا علاقة لسؤالي. سؤالي حول القيم الافتراضية في SQL Server ، وليس في BLL.
وأضاف المؤلف bzlm, مصدر