我的代码一直有问题。我已经开始学习EntityFramework,作为我使用微软虚拟学院网站的理由,他们有一个实体框架和ASP.NET的简短介绍。他们已经创建了这个存储库泛型类,它接受poco类。

public class Repository<T> where T : class
{
    private BlogDataContext context = null;
    protected DbSet<T> DbSet { get; set; }

    public Repository()
    {
        this.context = new BlogDataContext();
        DbSet = context.Set<T>();
    }

    public List<T> getAll()
    {
        return DbSet.ToList();
    }

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

    public void Add(T entity)
    {
        DbSet.Add(entity);
    }

    public void Update(T entity)
    {
        context.Entry<T>(entity).State = EntityState.Modified;
    }

    public void Delete(int id)
    {
        DbSet.Remove(DbSet.Find(id));
    }

    public void SaveChanges()
    {
        context.SaveChanges();
    }
}

当需要使用asp.net控件编辑数据库中的数据时,会出现问题,直到现在,我已经手动将数据绑定到控件,并通过使用Get(int Id)查找数据并进行更新来进行更新。最近我发现这个过程可以用objectdatasource控件自动化,但是update方法会抛出一个错误
附加“cardealership.datalayer.usersExtend”类型的实体
失败,因为同一类型的另一个实体已具有相同的
主键值。
UsersExtended是一个poco类。

最佳答案

不要使用Get方法,因为会将结果实体附加到您的上下文中,并且当您将断开连接的poco实体传递给具有相同id的Update方法时,ef将引发该异常。
如果实体继承自定义所有实体的pk属性的公共类,例如:

public class Entity
{
   public int Id{get;set;}
}

为了避免该问题,可以将以下方法添加到存储库中,以检查数据库中是否存在行:
public class Repository<T> where T : Entity
{
     //...
     public bool Exist(int id)
    {
      return DbSet.Exist(e=>e.Id==id);
    }
}

如果您没有这种设计,您可以在业务层中执行以下操作来进行检查:
var repository= new Repository<UsersExtended>();
bool exist= repository.GetAll().Exist(e=>e.Id==id);
if(exist)
{
   repository.Update(yourEntity)
}

另一件重要的事情,永远不要从dbset调用ToList扩展方法,这将把所有表加载到内存中。把它改成这样:
public IQueryable<T> GetAll()
{
    return DbSet;
}

始终尝试查询bl中的数据,并在查询调用结束时ToList扩展方法以仅加载所需的实体。

关于c# - EntityFramework储存库模式,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35993171/

10-11 17:22