4

我在每个表上都有几个属性,如 CreatedDate、ModifiedDate、VersionNo。每次修改实体时,我都需要更改/添加这些属性的值。我想我可以用这些属性创建一个基类,让实体从这个基类派生,在基于 ObjectState 的 SavingChanges 期间我可以更改值和保存,这样我的审计条目将与实体隔离,事情将是抽象的。但是由于我是 Entity Framework 的新手,我发现很难理解我将如何处理映射等。

如果有人可以提出实现这一点的想法,那将非常有帮助。存储库代码如下:

public class GeneralRepository<T> : IRepository<T> where T : class
{
    private ObjectSet<T> _set;
    private ObjectContext _context;


    public GeneralRepository(ObjectContext context)
    {
        if (context == null) throw new ArgumentNullException("context");
        _context = context;                 // sets the context
        _set = context.CreateObjectSet<T>(); // returns the Object Set
    }


    #region Methods to override to work with ObjectGraphs .

    /// <summary>
    /// To insert data from entity into a table.
    /// </summary>
    /// <param name="entity"></param>
    public virtual void Insert(T entity)
    {
        if (entity == null) throw new ArgumentNullException("entity");
        _set.AddObject(entity);
    }


    /// <summary>
    /// To delete entity from a table. 
    /// </summary>
    /// <param name="entity"></param>
    public virtual void Delete(T entity)
    {
        if (entity == null) throw new ArgumentNullException("entity");
        _set.Attach(entity);
        _set.DeleteObject(entity);
    }


    /// <summary>
    /// To update Entity into the table
    /// </summary>
    /// <param name="entity"></param>
    public virtual void Update(T entity)
    {
        if (entity == null) throw new ArgumentNullException("entity");
        _set.Attach(entity);
        _context.ObjectStateManager.ChangeObjectState(entity, EntityState.Modified);
    }

    /// <summary>
    /// To get th entire table contents
    /// </summary>
    /// <returns></returns>
    public IQueryable<T> GetAll()
    {
        return _set;
    }

}

4

3 回答 3

8

如果你先做数据库,你总是可以编辑 T4 模板来做你想做的事。在您的解决方案资源管理器中,展开 MyEntities.edmx 文件并找到 MyEntities.tt 文件并将其打开。

在第 307 行,您应该有以下方法:

public string EntityClassOpening(EntityType entity)
{
    return string.Format(
        CultureInfo.InvariantCulture,
        "{0} {1}partial class {2}{3}",
        Accessibility.ForType(entity),
        _code.SpaceAfter(_code.AbstractOption(entity)),
        _code.Escape(entity),
        _code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType)));
}

您需要将其更改为:

public string EntityClassOpening(EntityType entity)
{
    return string.Format(
        CultureInfo.InvariantCulture,
        "{0} {1}partial class {2}{3}",
        Accessibility.ForType(entity),
        _code.SpaceAfter(_code.AbstractOption(entity)),
        _code.Escape(entity),
        _code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType) ?? "MyBaseClass"));
}

您可以看到,如果没有提供 BaseType(您可以在 GUI 中这样做,但这是为了让单个实体从另一个实体继承),那么我们希望实体从 MyBaseClass 继承。

现在,当您保存它时,它将重新生成您的所有实体,它们现在将从 MyBaseClass 继承。就那么简单。

于 2013-09-04T01:42:18.780 回答
1

我认为您是正确的,创建一个名为“EntityBase”的基类或任何适合您偏好的名称并添加这些属性。

然后我会将上面的存储库类声明代码更改为:

public class GeneralRepository<T> : IRepository<T> where T : EntityBase

然后,您将能够根据需要在存储库中设置公共属性。

就映射而言,我肯定会看看 Entity Framework 5 Power Tools,因为您提到您首先是数据库,但是我的经验一直是使用流式 API 进行映射。

另外...一定要看看 DBContext 将为您提供的一些好处,而不是您当前在存储库中使用的 ObjectContext。

谢谢

于 2012-11-14T09:10:11.127 回答
0

创建一个像 BaseEntity 这样的基类,并在该类中包含您想要的属性。从 BaseEntity 派生您的实体并像这样定义您的存储库:

public class GeneralRepository<T> : IRepository<T> where T : BaseEntity

对于映射,有 3 种变体:每个层次结构的表、每个类型的表和每个具体类型的表。您可以在 Msdn 中找到有关它们的信息。

如果您有大部分不相关的实体,我会使用每个具体类型的表,并通过调用ToTable("Apples")您的EntityTypeConfiguration类(Fluent API)为每个实体创建单独的表。

于 2013-09-04T01:50:59.540 回答