EF CTP5 POCO, базовый класс и как реализовать наследование

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

inserted_by, inserted_at, updated_by, updated_at, deleted_by, deleted_at, timestamp

1. Если бы мне пришлось поместить это в базовый (возможно, абстрактный) класс POCO, какой была бы лучшая стратегия наследования для реализации этого. (Я использую GUID в качестве первичных ключей.)

Я не хочу использовать базовый класс ни для чего другого. В моем контексте БД; Я хотел бы использовать конечные классы POCO, соответствующие таблице db. DbSet, похоже, мне нужно жестко использовать DbSet, а затем использовать OfType для запроса :)

2 - Если наследование вырвано из контекста, что бы вы порекомендовали, ComplexType, может быть, интерфейс?


person hazimdikenli    schedule 03.02.2011    source источник


Ответы (2)


Я делаю именно это в EF4. Существует общий базовый класс репозитория:

public class GenericRepository<T> : IGenericRepository<T> where T : BaseEntity

Все репозитории сущностей наследуются от этого класса. Общие методы .Add() и .Update() автоматически устанавливают данные аудита:

public void Add(T entity)
{
        entity.CreatedOn = DateTime.UtcNow;
        entity.CreatedBy = UserName;
        entity.LastModifiedOn = entity.CreatedOn;
        entity.LastModifiedBy = entity.CreatedBy;
        ObjectContext.AddObject(GetEntitySetName<T>(), entity);
}

public void Update(T entity)
{
        T originalEntity = ObjectSet.Single(t => t.Id == entity.Id);            
        entity.CreatedOn = originalEntity.CreatedOn;
        entity.CreatedBy = originalEntity.CreatedBy;
        entity.LastModifiedOn = DateTime.UtcNow;
        entity.LastModifiedBy = UserName;
        ObjectSet.ApplyCurrentValues(entity);
}

Итак, вы можете видеть, что он не входит в базовый класс POCO BaseEntity, потому что это не входит в обязанности POCO. Вместо этого он принадлежит репозиторию.

person JK.    schedule 03.02.2011
comment
как вы это делаете (я не думаю, что вы используете POCO) - person hazimdikenli; 03.02.2011
comment
+1 я согласен с этим. обновление метки времени является проблемой базы данных, размещение этой логики в POCO перестанет быть POCO. Наличие метки времени не является разумной причиной для реализации наследования с помощью EF. - person RPM1984; 03.02.2011
comment
@RPM: я не согласен - если вы используете Timestamp, вам обычно нужно сопоставить его с вашей сущностью и установить его как ConcurrencyCheckAttribute (сначала код) или фиксированный режим параллелизма (чистый EF4). Если вы не сопоставляете метку времени с сущностью, это равносильно тому, что вы вообще ее не используете. - person Ladislav Mrnka; 03.02.2011
comment
@Ladislav - у меня есть поле с именем DateModified с фиксированным режимом параллелизма, сопоставленное с моей сущностью. Это нормально, ИМО, потому что это все еще POCO, просто с другим свойством. Разница заключается в том, что логика для этой метки времени находится в EF, а не в самом POCO. - person RPM1984; 03.02.2011
comment
@RPM: Возможно, если вы думаете, что Timestamp сама по себе нарушает значение POCO, вы правы. Но я буду придерживаться временных меток. Я считаю, что есть веская причина, по которой существуют типы данных версии строки (например, SQL Timestamp). - person Ladislav Mrnka; 03.02.2011
comment
речь идет не о наличии свойства TimeStamp/RowVersion в POCO/Entity, а о наличии EntityBase и его реализации либо как ComplexType, либо как Inheritance. - person hazimdikenli; 03.02.2011

Вам нужно наследование TPC (таблица для класса или таблица для конкретного типа). Проверьте эта статья о сопоставлении TPC CTP5.

person Ladislav Mrnka    schedule 03.02.2011
comment
Если я использую TPC, из чего состоят мои DbSet, могу ли я основывать их на конкретном типе или на базовом типе? - person hazimdikenli; 03.02.2011
comment
@hazimdikenli: при использовании любого типа наследования набором является DbSet‹BaseType›, но сущности в наборе относятся к производным типам. Вы можете использовать OfType для запроса только производных типов. - person Ladislav Mrnka; 03.02.2011
comment
тогда он не собирается предоставлять мне то, что мне нужно. - person hazimdikenli; 08.02.2011
comment
@hazimdikenli: Почему бы и нет? Вы всегда можете определить пользовательские свойства в вашем DbContext, которые будут возвращать IQueryable‹yourtype› и использовать DbSet.OfType‹yourtype› для внутреннего использования. Вы можете попробовать определить DbSet вашего производного типа - я не пробовал, я пользователь, он работает с базовым типом. - person Ladislav Mrnka; 08.02.2011