使用通用类型的EntityFramework进行CRUD操作

6

我希望能够使用一种通用的T类型服务类,使我能够动态地查询数据库。例如,通常我会像这样执行删除记录的操作:

public void Delete(Post post)
{
    this._context.Posts.Remove(post);
}

我希望能够做到这一点

public void Delete(T post)
{
    this._context<T>.Remove(post);
}

我在这里找到了一篇文章,大致涉及了这个问题,但似乎实现起来并不太干净。 https://blog.magnusmontin.net/2013/05/30/generic-dal-using-entity-framework/


2
只需使用 _context.Set<T>().Remove(post) - Evk
在网络上,你可以找到许多关于使用EF实现通用仓储库的文章,例如这篇或者这篇 - Fabjan
2个回答

6
你需要使用 DbContext.Sethttps://msdn.microsoft.com/zh-cn/library/gg679544(v=vs.113).aspx

返回一个非泛型 DbSet 实例,以便在上下文和底层存储中访问给定类型的实体。

public void Delete<T>(T post)
    where T : class
{
    this._context.Set<T>.Remove(post);
}

以后,您还可以根据以下内容查询:
this._context.Set<T>.AsQueryable().Where(predicate);

在这种情况下,“predicate”将是一个“Expression<Func<T, bool>>”。因此,您可以拥有一个通用的查询方法:
public IEnumerable<T> Query<T>(Expression<Func<T, bool>> predicate)
    where T : class
{
    return this._context.Set<T>().AsQueryable().Where(predicate).ToList();
}

...但我现在有点偏离问题了!

(这段话与IT技术无关)

尝试了这个,但是出现了错误。类型“T”必须是引用类型,才能将其用作泛型类型或方法“DbContext.Set<TEntity>()”中的参数“TEntity”。 - Dan Hastings
啊-请看我的更新Query-你需要where子句。 - Alex

1
你可以使用通用存储库模式。
public class Repository<TEntity> where TEntity : class
{
    private dynamic _context;
    private DbSet<TEntity> _dbSet;

    protected DbContext Context
    {
        get
        {
            if (_context == null)
            {
                _context = DataContextFactory.GetDataContext();
            }

            return _context;
        }
    }

    protected DbSet<TEntity> DBSet
    {
        get
        {
            if (_dbSet == null)
            {
                _dbSet = this.Context.Set<TEntity>();
            }

            return _dbSet;
        }
    }

    public virtual IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> predicate, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderExpression = null)
    {
        return this.GetQuery(predicate, orderExpression).AsEnumerable();
    }

    public virtual IQueryable<TEntity> GetQuery(Expression<Func<TEntity, bool>> predicate = null, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderExpression = null)
    {
        IQueryable<TEntity> qry = this.DBSet;

        if (predicate != null)
            qry = qry.Where(predicate);

        if (orderExpression != null)
            return orderExpression(qry);


        return qry;
    }

    public virtual void Insert<T>(T entity) where T : class
    {
        DbSet<T> dbSet = this.Context.Set<T>();
        dbSet.Add(entity);
    }

    public virtual void Insert(TEntity entity)
    {
        this.DBSet.Add(entity);
    }

    public virtual void Update<T>(T entity) where T : class
    {
        DbSet<T> dbSet = this.Context.Set<T>();
        dbSet.Attach(entity);
        this.Context.Entry(entity).State = EntityState.Modified;
    }

    public virtual void Update(TEntity entity)
    {
        this.Attach(entity);
        this.Context.Entry(entity).State = EntityState.Modified;
    }

    public virtual void Delete<T>(T entity) where T : class
    {
        DbSet<T> dbSet = this.Context.Set<T>();

        if (this.Context.Entry(entity).State == EntityState.Detached)
            dbSet.Attach(entity);

        dbSet.Remove(entity);

    }

    public virtual void Delete(TEntity entity)
    {
        if (this.Context.Entry(entity).State == EntityState.Detached)
            this.Attach(entity);

        this.DBSet.Remove(entity);

    }

    public virtual void Delete<T>(object[] id) where T : class
    {
        DbSet<T> dbSet = this.Context.Set<T>();
        T entity = dbSet.Find(id);
        dbSet.Attach(entity);
        dbSet.Remove(entity);

    }

    public virtual void Delete(object id)
    {
        TEntity entity = this.DBSet.Find(id);
        this.Delete(entity);
    }


    public virtual void Attach(TEntity entity)
    {
        if (this.Context.Entry(entity).State == EntityState.Detached)
            this.DBSet.Attach(entity);
    }

    public virtual void SaveChanges()
    {
        this.Context.SaveChanges();
    }
}

使用方法:

public class Sample
{
    public void AddNewPerson(Person newPerson)
    {
        var personRepo = new Repository<Person>();
        personRepo.Insert(newPerson);
        personRepo.SaveChanges();
    }

    public void DeletePerson(int personId)
    {
        var personRepo = new Repository<Person>();
        Person person= personRepo.Find(p => p.Id == personId).SingleOrDefault();
        personRepo.Delete(person);
    }
}

如果Person有像List<Address>这样的子对象层次结构,这个代码还能正常工作吗? - Usama Aziz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接