تعيين فئة مشتقة إلى جدول في Linq-to-SQL
-
20-09-2019 - |
سؤال
لدي فئة أساسية مجردة لخصائص التدقيق.للإيجاز نقول أن لديها خاصية واحدة
Public MustInherit Class AbstractAuditableEntity
...
Public Property CreatedTime() As DateTimeOffset
...
End Class
ومن ثم ترث كائنات المجال القابلة للتدقيق من هذه الفئة
Public Class Source
Inherits AbstractAuditableEntity
...
Public Property SourceId() As String
...
End Class
لدي الجدول التالي DDL الذي أريد تعيين كائن المجال الخاص بي "المصدر" إليه.العلاقة بشكل أساسي بين كل كائن مجال (ملموس) وجدول هي 1-1، حيث يحتوي كل جدول على عمود التدقيق المطلوب.
CREATE TABLE Source
(
SourceID VARCHAR(10) NOT NULL,
CreatedTime DATETIMEOFFSET(3) NOT NULL,
CONSTRAINT PK_Source PRIMARY KEY (SourceID))
GO
باستخدام ملف تعيين خارجي، ستكون محاولتي الأولى لتعيين الفصل على الجدول بحماقة:
<?xml version="1.0" encoding="utf-8"?>
<Database Name="" xmlns="http://schemas.microsoft.com/linqtosql/mapping/2007">
<Table Name="Source" Member="Sources">
<Type Name ="Source">
<Column Name="SourceID" Member="SourceID" IsPrimaryKey="true" CanBeNull="false"/>
<Column Name="CreatedTime" Member="CreatedTime" />
</Type>
</Table>
</Database>
ولكن هذا يولد الاستثناء التالي:
لا يحتوي العمود أو الارتباط "CreatedTime" في التعيين على عضو مطابق في النوع "Source". تعيين الأعضاء من النوع الجذري الأعلى غير مدعوم.
في سياق طبقة الثبات الخاصة بي، لا أحاول تمثيل تسلسل هرمي للوراثة على هذا النحو، ولكن في سياق تطبيقي، أستخدم ببساطة فئة أساسية لتوفير الخصائص المطلوبة من قبل جميع كائنات المجال الخاصة بي.مع الكثير من العبث بملف التعيين الخاص بي (بما في ذلك تعيين أعمدة التدقيق إلى نوع AbstractAuditableEntity الأساسي) والقراءة، لا أستطيع تحقيق ما أعتبره مهمة ORM مباشرة.
أي أفكار أو اقتراحات سيكون موضع ترحيب كبير!شكرًا
المحلول
أظهر كيلي نموذجًا رائعًا لكيفية القيام بذلك - ولكنك في الأساس قد تجاوزت أحد قيود Linq-to-SQL.
إنه يعمل بشكل رائع إذا قمت بتعيين جدول قاعدة البيانات بنسبة 1:1 أكثر أو أقل لكائنات المجال الخاص بك.لكنها ضعيفة وتتسبب في الكثير من العمل الإضافي عندما لا يعود الأمر كذلك.
في مثل هذه الحالة، بمجرد حصولك على وراثة كائن المجال والأشياء الأخرى التي تحتاج إلى تعيينها إلى جداول قاعدة البيانات، فمن الأفضل أن تقوم بمراجعة ADO.NET Entity Framework بدلاً من ذلك.تم تصميم EF خصيصًا للتعامل مع هذه الأشياء - إذا فكرت يومًا "أحتاج إلى ذلك خريطة أشيائي......" إذًا يجب أن تفكر في EF!:-)
من المؤكد أن شحن EF الحالي في .NET 3.5 SP1 له ثآليله ومضايقاته، ولكن EF 4 الذي يعد جزءًا من موجة .NET 4.0 (والتي يجب أن يتم شحنها قبل نهاية هذا العام 2009)، يجب أن يحل عددًا كبيرًا من هذه المشاكل الثآليل!
تفحص ال مدونة فريق ADO.NET Entity Framework لبعض الإعلانات التشويقية لما ستجلبه لنا EF4 جميعًا!
مارك
نصائح أخرى
أعتقد أنك تحاول محاكاة مجالات التدقيق مثل Ruby on Rails updated_on
, created_on
.إذا كان الأمر كذلك، فإليك كيف أنجزت شيئًا مشابهًا باستخدام هذا المنشور كنقطة بدايةhttp://weblogs.asp.net/stevesheldon/archive/2008/02/23/a-method-to-handle-audit-fields-using-linq-to-sql.aspx
لقد قمت بتنفيذ واجهة في مساحة اسم النماذج كما يلي:
public interface IAuditable
{
DateTime CreatedOn { get; set; }
string CreatedBy { get; set; }
DateTime? ChangedOn { get; set; }
string ChangedBy { get; set; }
}
ثم قمنا بتوسيع الفئات الجزئية لكيانات البيانات التي تحتوي على هذه الحقول:
public partial class DataModelIWantToAudit : IAuditable
{
}
ومن ثم تجاوز SubmitChanges
على ال DataContext
للتحقق من تنفيذ الواجهة بسحر Linq OfType<>
:
public override void SubmitChanges(ConflictMode failureMode)
{
//Updates
foreach (var updatedModel in GetChangeSet().Updates.OfType<IAuditable>())
{
updatedModel.ChangedOn = DateTime.Now;
updatedModel.ChangedBy = Membership.GetUser().UserName;
}
//Inserts
foreach (var insertedModel in GetChangeSet().Inserts.OfType<IAuditable>())
{
insertedModel.CreatedOn = DateTime.Now;
insertedModel.CreatedBy = Membership.GetUser().UserName;
}
base.SubmitChanges(failureMode);
}
امل ان يساعد!-كيلي