Отображение производного класса в таблицу в Linq-to-SQL - PullRequest
3 голосов
/ 28 августа 2009

У меня есть абстрактный базовый класс для свойств аудита. Для краткости скажем, что у него есть одно свойство

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.

Любые мысли или предложения будут приветствоваться! Спасибо

Ответы [ 2 ]

5 голосов
/ 28 августа 2009

Я предполагаю, что вы пытаетесь эмулировать поля аудита, такие как 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

Я реализовал интерфейс в пространстве имен Models следующим образом:

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);
}

Надеюсь, это поможет! -Kelly

1 голос
/ 28 августа 2009

Келли показал отличный пример того, как это сделать, но вы в основном столкнулись с одним из ограничений 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 принесет нам всем!

Марк

...