在从通用接口继承的泛型类中混淆字段赋值

时间:2014-11-05 10:12:33

标签: c# entity-framework generics entity dbcontext

我正在阅读存储库模式设计。 This article非常好,但我不了解构造函数中的一些内容。

在此代码中:

public interface IRepository<T> where T : class
    {
        IQueryable<T> GetAll(); 
        T GetById(int id); 
        void Add(T entity);
        void Update(T entity);
        void Delete(T entity);
        void Delete(int id);
    } 

    /// <summary>
    /// The EF-dependent, generic repository for data access
    /// </summary>
    /// <typeparam name="T">Type of entity for this Repository.</typeparam>
    public class MyRepository<T> : IRepository<T> where T : class
    {
        public MyRepository(DbContext dbContext)
        {
            if (dbContext == null) 
                throw new ArgumentNullException("Null DbContext");
            DbContext = dbContext;
            DbSet = DbContext.Set<T>();
        }

        protected DbContext DbContext { get; set; }

        protected DbSet<T> DbSet { get; set; }

        public virtual IQueryable<T> GetAll()
        {
            return DbSet;
        }

        public virtual T GetById(int id)
        {           
            return DbSet.Find(id);
        }

        public virtual void Add(T entity)
        {
            DbEntityEntry dbEntityEntry = DbContext.Entry(entity);
            if (dbEntityEntry.State != EntityState.Detached)
            {
                dbEntityEntry.State = EntityState.Added;
            }
            else
            {
                DbSet.Add(entity);
            }
        }

        public virtual void Update(T entity)
        {
            DbEntityEntry dbEntityEntry = DbContext.Entry(entity);
            if (dbEntityEntry.State == EntityState.Detached)
            {
                DbSet.Attach(entity);
            }  
            dbEntityEntry.State = EntityState.Modified;
        }

        public virtual void Delete(T entity)
        {
            DbEntityEntry dbEntityEntry = DbContext.Entry(entity);
            if (dbEntityEntry.State != EntityState.Deleted)
            {
                dbEntityEntry.State = EntityState.Deleted;
            }
            else
            {
                DbSet.Attach(entity);
                DbSet.Remove(entity);
            }
        }

        public virtual void Delete(int id)
        {
            var entity = GetById(id);
            if (entity == null) return; // not found; assume already deleted.
            Delete(entity);
        }
    }

在它的构造函数中,我读到了这个:

DbContext = dbContext;
DbSet = DbContext.Set<T>();

可能它意味着什么,但它对我没有意义,因为DbContext的类型不是存储对象引用的变量。我总是从DbContext继承并创建我自己的DbContext,然后创建它的实例/元素。这里有什么特别的意义吗?我想知道为什么作者没有这样写这些行:

MyDbContext dbContext = new MyDbContext();

由于

1 个答案:

答案 0 :(得分:3)

进一步查看该类的源代码,您将看到:

protected DbContext DbContext { get; set; }

这声明了DbContext类型的属性,也称为DbContext。在ctor中分配时,您将分配给此属性。

(作用域规则在C#中的工作方式意味着在构造函数本身内,DbContext解析为该名称的类属性,而不是类型DbContext。)

是的,这可能令人困惑。出于这个原因,作者可能更好地为属性赋予与其类型不同的名称 - 但这种命名实际上相当普遍。

至少应该改写ctor:

public MyRepository(DbContext dbContext)
{
    if (dbContext == null) 
        throw new ArgumentNullException("Null DbContext");
    this.DbContext = dbContext;
    this.DbSet = this.DbContext.Set<T>();
}