将派生类映射到Linq-to-SQL中的表

Per*_* P. 3 mapping orm inheritance derived-class linq-to-sql

我有一个用于审计属性的抽象基类.为简洁起见说它有一个属性

Public MustInherit Class AbstractAuditableEntity  
  ...  
  Public Property CreatedTime() As DateTimeOffset 
  ...
End Class  
Run Code Online (Sandbox Code Playgroud)

然后我的可审计域对象继承自此类

Public Class Source  
  Inherits AbstractAuditableEntity  
  ...        
  Public Property SourceId() As String  
  ...
End Class  
Run Code Online (Sandbox Code Playgroud)

我有下面的表DDL,我想要映射我的域对象"源".基本上每个(具体)域对象和表之间的关系是1-1,每个表都有所需的审计列.

CREATE TABLE Source  
(  
   SourceID VARCHAR(10) NOT NULL,   
   CreatedTime   DATETIMEOFFSET(3) NOT NULL,  
   CONSTRAINT PK_Source PRIMARY KEY (SourceID))  
GO
Run Code Online (Sandbox Code Playgroud)

使用外部映射文件我第一次尝试将类映射到表将是愚蠢的:

<?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>
Run Code Online (Sandbox Code Playgroud)

但是,这会产生以下异常:

映射中的列或关联"CreatedTime"在"Source"类型中没有对应的成员.不支持从上面的根类型映射成员.

在我的持久层的上下文中,我不是试图表示继承层次结构,但是在我的应用程序的上下文中,我只是使用基类来提供我所有域对象所需的属性.随着我的映射文件的大量摆弄(包括将审计列映射到基本的AbstractAuditableEntity类型)和阅读,我无法实现我认为相当简单的ORM任务.

任何想法或建议都会受到欢迎!谢谢

Kel*_*ams 6

我猜你是试图模仿像Ruby on Rails的审计领域updated_on,created_on.如果是这样的话,这就是我如何使用这篇文章作为起点完成类似的工作 http://weblogs.asp.net/stevesheldon/archive/2008/02/23/a-method-to-handle-audit-fields-using -linq到sql.aspx

我在Models名称空间中实现了一个接口,如下所示:

public interface IAuditable
{
    DateTime CreatedOn { get; set; }
    string CreatedBy { get; set; }
    DateTime? ChangedOn { get; set; }
    string ChangedBy { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

然后扩展具有以下字段的数据实体的部分类:

public partial class DataModelIWantToAudit : IAuditable
{
}
Run Code Online (Sandbox Code Playgroud)

然后推翻了SubmitChangesDataContext检查使用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);
}
Run Code Online (Sandbox Code Playgroud)

希望有所帮助!-Kelly