Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 实体框架的DbManager助手类_C#_Entity Framework_Dbcontext - Fatal编程技术网

C# 实体框架的DbManager助手类

C# 实体框架的DbManager助手类,c#,entity-framework,dbcontext,C#,Entity Framework,Dbcontext,我正在尝试做一个通用的Db cotext helper\manager,这样我就可以在许多具有不同数据库的项目中使用它作为dll 我曾尝试在我的一个项目中使用它,但我对Add和Edit方法中的attach和detach感到困惑。由于entity对象不能被多个IEntityChangeTracker实例引用,我遇到了错误 有人能帮我把这位经理弄得十全十美吗 public class DbEntityManager<T> : IDisposable where T : class, IE

我正在尝试做一个通用的Db cotext helper\manager,这样我就可以在许多具有不同数据库的项目中使用它作为dll

我曾尝试在我的一个项目中使用它,但我对Add和Edit方法中的attach和detach感到困惑。由于entity对象不能被多个IEntityChangeTracker实例引用,我遇到了错误

有人能帮我把这位经理弄得十全十美吗

public class DbEntityManager<T> : IDisposable where T : class, IEntity
    {
        public DbContext DbEntities { get; set; }

        public virtual int AddNewObject(T objToAdd)
        {
            DbEntities.Set<T>().Add(objToAdd);
            return DbEntities.SaveChanges();
        }

        public virtual int EditObject(T objToEdit)
        {
            if (DbEntities.Entry(objToEdit).State == EntityState.Detached)
            {
                DbEntities.Set<T>().Attach(objToEdit);
                DbEntities.Entry(objToEdit).State = EntityState.Modified;
            }
            else
            {
                DbEntities.Entry(objToEdit).State = EntityState.Modified;
            }

            return DbEntities.SaveChanges();
        }

        public virtual int DeleteObject(T objToDelete)
        {
            DbEntities.Set<T>().Remove(objToDelete);
            return DbEntities.SaveChanges();
        }

        public virtual List<T> GetAllList()
        {
            return DbEntities.Set<T>().ToList();
        }

        public virtual T GetObjectById(int id)
        {
            return DbEntities.Set<T>().AsEnumerable().SingleOrDefault(x => x.Id == id);
        }

        public DbEntityManager(DbContext db)
        {
            DbEntities = db;
        }

        public void Dispose()
        {
            this.Dispose();
        }
    }
下面是一个类的示例:

public partial class Address : IEntity
    {
        public Address()
        {
            this.Customers = new HashSet<Customer>();
        }

        public int AddressID { get; set; }
        public string Address_Country { get; set; }
        public string Address_City { get; set; }
        public string Address_Street { get; set; }
        public string Address_ZipCode { get; set; }

        public virtual ICollection<Customer> Customers { get; set; }

        public int Id
        {
            get { return AddressID; }
        }
    }
或:


在我这么做之前,我在互联网上搜索了一下,看看是否已经存在这样的类,但我没有找到任何类。因此,如果有人知道已经用这些函数创建了一个类,我很乐意使用它。

我更喜欢做以下事情:

public virtual int EditObject(T objToEdit)
    {
        var curval = DB.Set<T>().FirstOrDefault(x => x.Id == objToEdit.Id);
        //You may want to make all your entities inherit from the same 
        //baseclass to get Id
        if (curval == null)
        {
            DB.Set<T>.Add(objToEdit);
        }
        else
        {
            DB.Entry(curval).CurrentValues.SetValues(objToEdit);
            DB.Entry(curval).State = System.Data.Entity.EntityState.Modified;
        }
        return DB.SaveChanges();
    }

修改此代码以处理模型也很容易。

我通常将存储库与模式一起使用

尝试实现这样一个基本存储库,然后使用相同的方法创建派生实体类型

这将有助于保持代码干燥

public interface IBaseRepository<TEntity> : IDisposable
     where TEntity : class
    {
        void Delete(object id);
        void Delete(TEntity entity);
        TEntity Find(params object[] keyValues);
        void Insert(TEntity entity);
        void InsertRange(IEnumerable<TEntity> entities);
        IQueryable<TEntity> SelectQuery(string query, params object[] parameters);
        void Update(TEntity entity);
        void RefreshEntityContext(TEntity entity);
    }
希望这有帮助

编辑:好的,下面是实现的摘录,与我实现它的方式类似:

namespace ContosoUniversity.DAL
{
    public class GenericRepository<TEntity> where TEntity : class
    {
        internal SchoolContext context;
        internal DbSet<TEntity> dbSet;

        public GenericRepository(SchoolContext context)
        {
            this.context = context;
            this.dbSet = context.Set<TEntity>();
        }

        public virtual IEnumerable<TEntity> Get(
            Expression<Func<TEntity, bool>> filter = null,
            Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
            string includeProperties = "")
        {
            IQueryable<TEntity> query = dbSet;

            if (filter != null)
            {
                query = query.Where(filter);
            }

            foreach (var includeProperty in includeProperties.Split
                (new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
            {
                query = query.Include(includeProperty);
            }

            if (orderBy != null)
            {
                return orderBy(query).ToList();
            }
            else
            {
                return query.ToList();
            }
        }

        public virtual TEntity GetByID(object id)
        {
            return dbSet.Find(id);
        }

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

        public virtual void Delete(object id)
        {
            TEntity entityToDelete = dbSet.Find(id);
            Delete(entityToDelete);
        }

        public virtual void Delete(TEntity entityToDelete)
        {
            if (context.Entry(entityToDelete).State == EntityState.Detached)
            {
                dbSet.Attach(entityToDelete);
            }
            dbSet.Remove(entityToDelete);
        }

        public virtual void Update(TEntity entityToUpdate)
        {
            dbSet.Attach(entityToUpdate);
            context.Entry(entityToUpdate).State = EntityState.Modified;
        }
    }
}
现在,您可以从GenericRepository继承存储库,并提供所有基本CRUD操作

从,
为什么要重新发明轮子。试试看,它是一个通用的存储库,是的,另一个具有实体框架扩展,并使用重用策略而不是服务方法。另外,它完全可测试,无需模拟

IQueryRepository queryRepository = new EntityFrameworkQueryRepository(new YourDbContext()) ;
var address = queryRepository.GetEntity<Address>(
    p => p.AddressID == 2,
    new AsNoTrackingQueryStrategy(),
    new EagerLoadingQueryStrategy<Address>(
        p => p.Customers));

注意:不要忘记在您的存储库中注入:

实体框架已经使用了存储库和工作单元设计模式,不需要帮助人员使用该框架

为什么需要这样做?您希望从抽象中得到什么?这个问题应该更适合我所说的,我想将它用作具有不同db的许多项目的dll。我不想在每个项目中都创建添加、保存更改和所有这些。实际上,我自己也构建了类似的东西。本质上,为了回答@DeanWard的问题,它是一个完全通用的数据访问类——从FooT obj的C意义上来说,它与任何数据存储方法SQL、XML等都无关。在一个类中,我将它分为两个——通用数据管理器和将其连接到不同数据源的各种适配器。一个适配器是用于使用实体框架的SQL的,因此将完全满足您所描述的需求。如果你感兴趣的话,我打算在未来几天的某个时候把它放到NuGet上。你说这是一个围绕DbContext的包装器,但它看起来确实是围绕DbSet的包装器。你是否清楚你为什么要这样做,你的动机,在这里应该帮助我们和你自己更好地理解为什么。如果没有IEntity和DbEntities的定义,这段代码一点也不清楚。接口在这里对我没有帮助。@user2254436-你需要实现接口,就像我在我的项目中所做的那样,它促进了可重用存储库基类的实现,如上面共享的“UnitOfWork”实现中所述。你检查过这个模式了吗?
public virtual int EditObject(T objToEdit)
    {
        var curval = DB.Set<T>().FirstOrDefault(x => x.Id == objToEdit.Id);
        //You may want to make all your entities inherit from the same 
        //baseclass to get Id
        if (curval == null)
        {
            DB.Set<T>.Add(objToEdit);
        }
        else
        {
            DB.Entry(curval).CurrentValues.SetValues(objToEdit);
            DB.Entry(curval).State = System.Data.Entity.EntityState.Modified;
        }
        return DB.SaveChanges();
    }
public interface IBaseRepository<TEntity> : IDisposable
     where TEntity : class
    {
        void Delete(object id);
        void Delete(TEntity entity);
        TEntity Find(params object[] keyValues);
        void Insert(TEntity entity);
        void InsertRange(IEnumerable<TEntity> entities);
        IQueryable<TEntity> SelectQuery(string query, params object[] parameters);
        void Update(TEntity entity);
        void RefreshEntityContext(TEntity entity);
    }
namespace ContosoUniversity.DAL
{
    public class GenericRepository<TEntity> where TEntity : class
    {
        internal SchoolContext context;
        internal DbSet<TEntity> dbSet;

        public GenericRepository(SchoolContext context)
        {
            this.context = context;
            this.dbSet = context.Set<TEntity>();
        }

        public virtual IEnumerable<TEntity> Get(
            Expression<Func<TEntity, bool>> filter = null,
            Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
            string includeProperties = "")
        {
            IQueryable<TEntity> query = dbSet;

            if (filter != null)
            {
                query = query.Where(filter);
            }

            foreach (var includeProperty in includeProperties.Split
                (new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
            {
                query = query.Include(includeProperty);
            }

            if (orderBy != null)
            {
                return orderBy(query).ToList();
            }
            else
            {
                return query.ToList();
            }
        }

        public virtual TEntity GetByID(object id)
        {
            return dbSet.Find(id);
        }

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

        public virtual void Delete(object id)
        {
            TEntity entityToDelete = dbSet.Find(id);
            Delete(entityToDelete);
        }

        public virtual void Delete(TEntity entityToDelete)
        {
            if (context.Entry(entityToDelete).State == EntityState.Detached)
            {
                dbSet.Attach(entityToDelete);
            }
            dbSet.Remove(entityToDelete);
        }

        public virtual void Update(TEntity entityToUpdate)
        {
            dbSet.Attach(entityToUpdate);
            context.Entry(entityToUpdate).State = EntityState.Modified;
        }
    }
}
IQueryRepository queryRepository = new EntityFrameworkQueryRepository(new YourDbContext()) ;
var address = queryRepository.GetEntity<Address>(
    p => p.AddressID == 2,
    new AsNoTrackingQueryStrategy(),
    new EagerLoadingQueryStrategy<Address>(
        p => p.Customers));
IRepository repository = new EntityFrameworkRepository(new YourDbContext()) ;
var address = new Address{ Address_City = "Leeds" };
repository.Add(address);
repository.Save()