C# 抽象类泛型属性

标签 c# entity-framework-4 abstract-class poco

考虑以下代码:

public abstract class RepositoryBase<T> where T : class
{
    #region Members

    private MyContext dataContext;
    private readonly IDbSet<T> dbset;

    #endregion

    protected RepositoryBase(IDatabaseFactory databaseFactory)
    {
        DatabaseFactory = databaseFactory;
        dbset = DataContext.Set<T>();
    }

    protected IDatabaseFactory DatabaseFactory
    {
        get; private set;
    }

    protected MyContext DataContext
    {
        get { return dataContext ?? (dataContext = DatabaseFactory.Get()); }
    }

    public virtual void Delete(T entity)
    {
        dbset.Remove(entity);
    }

我想用下面的方法替换 Delete 方法,因为我更愿意简单地将对象中的 Deleted 字段设置为 true 以指示它已被删除,而不是真正删除它。

    public virtual void Delete(T entity)
    {
        entity.Deleted = true;
        dbset.Attach(entity);
        dataContext.Entry(entity).State = EntityState.Modified;
    }

我正在使用 POCO 实体,并且所有实体中都存在 Deleted 属性。但是,在上面的代码中,实体的类型是 T,而 T“不知道”它可以表示的所有对象中都有一个 Deleted 属性。解决这个问题最优雅的方法是什么?

顺便说一句,我想在我的抽象类中以类似的方式访问其他字段(DateCreated、CreatedBy、DateModified 和 ModifiedBy)。

更新:我尝试了接口(interface)和抽象类的解决方案,一开始看起来不错,但后来在编译时两种情况都出现以下错误消息:

Error 11 The type 'MyProject.Domain.Person' cannot be used as type parameter 'T' in the generic type or method 'MyProject.Data.Infrastructure.RepositoryBase'. There is no implicit reference conversion from 'MyProject.Domain.Person' to 'MyProject.Domain.AbstractEntity'.

这里是错误消息所指的代码:

namespace MyProject.Data
{ 
    public class PersonRepository : RepositoryBase<Person>, IPersonRepository
    {
        public PersonRepository(IDatabaseFactory databaseFactory)
            : base(databaseFactory)
        {
        }
    }

    public interface IPersonRepository : IRepository<Person>
    {

    }
}

更新 2:

我终于让它与 SLaks 提出的解决方案一起工作。我使用了一个接口(interface),并修改了生成所有 POCO 实体的模板,以便它们都派生自以下 IEntity 接口(interface):

namespace MyProject.Domain
{
    public interface IEntity
    {
        System.DateTime CreatedDate
        {
            get;
            set;
        }

        string CreatedBy
        {
            get;
            set;
        }

        System.DateTime ModifiedDate
        {
            get;
            set;
        }

        string ModifiedBy
        {
            get;
            set;
        }

        bool Deleted
        {
            get;
            set;
        }
    }
}

使用抽象实体类会更复杂,因为抽象类中的所有属性都必须在实体类中被覆盖。

最佳答案

将您的 Deleted 属性放入一个接口(interface)(比方说,IDeleteable),并使用通用约束来约束该类:

public interface IDeleteable { Boolean Deleted { get; set; } }

public abstract class RepositoryBase<T> where T : class, IDeleteable

编辑:我认为这是隐含的,但你需要在你的实体类中实现接口(interface),例如

public class Person : IDeleteable { ... }

关于C# 抽象类泛型属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8796076/

相关文章:

.net - 如何在 Entity Frameworks 4.0 模型中指定 SQL Server XML 数据类型?

.net - EF - 添加到由 Id 设置的关联

c# - 在抽象类中使用构造函数

python - Django:如何在 Django 中实现类的层次结构?

c# - SelectListItem/更新申请表MVC3 4.0到MVC5 4.5.1/ View 扩展方法

c# - 在 C# 中重命名目录

c# - 查找特定子文件夹

c# - Entity Framework 的双重自引用属性

scala - 从基本抽象类构造子类

c# - 在C#中调用C/C++方法