gpt4 book ai didi

entity-framework - EF4 CTP5 的存储库模式

转载 作者:行者123 更新时间:2023-12-04 16:36:37 25 4
gpt4 key购买 nike

我正在尝试使用 ef4 ctp5 实现存储库模式,我想出了一些东西,但我不是 ef 专家所以 我想知道我做的好不好。

这是我的数据库上下文

public class Db : DbContext
{
public DbSet<User> Users { get; set; }
public DbSet<Role> Roles { get; set; }
}

和存储库:(简化)
public class Repo<T> : IRepo<T> where T : Entity, new()
{
private readonly DbContext context;

public Repo()
{
context = new Db();
}

public IEnumerable<T> GetAll()
{
return context.Set<T>().AsEnumerable();
}

public long Insert(T o)
{
context.Set<T>().Add(o);
context.SaveChanges();
return o.Id;
}
}

最佳答案

您需要退后一步,考虑存储库应该做什么。存储库用于检索记录、添加记录和更新记录。您创建的存储库几乎不处理第一种情况,处理第二种情况但效率不高,并且根本不处理第三种情况。

大多数通用存储库都有一个类似的接口(interface)

public interface IRepository<T> where T : class
{
IQueryable<T> Get();
void Add(T item);
void Delete(T item);
void CommitChanges();
}

对于检索记录,您不能只使用 AsEnumerable() 调用整个集合因为这会将该表的每个数据库记录加载到内存中。如果您只想要用户名为 username1 的用户,您不需要为数据库下载每个用户,因为这将对数据库性能造成非常大的影响,并且对客户端性能造成很大的影响,根本没有任何好处。

相反,正如您将在我上面发布的界面中看到的那样,您想要返回 IQueryable<T>目的。 IQuerable s 允许调用存储库的任何类使用 Linq 并向数据库查询添加过滤器,一旦 IQueryable 运行,它就完全在数据库上运行,只检索您想要的记录。数据库在排序和过滤数据方面比你的系统好得多,所以最好尽可能多地在数据库上做。

现在关于插入数据,您有正确的想法,但您不想调用 SaveChanges()立即地。原因是最好调用 Savechanges()在您的所有数据库操作都已排队之后。例如,如果你想在一个操作中创建一个用户和他的个人资料,你不能通过你的方法,因为每个 Insert call 将导致数据被插入到数据库中。

相反,您想要的是分离出 Savechanges()调用 CommitChanges我上面的方法。

这也需要处理更新数据库中的数据。为了更改实体的数据, Entity Framework 会跟踪它收到的所有记录并监视它们以查看是否进行了任何更改。但是,您仍然必须告诉 Entity Framework 将所有更改的数据发送到数据库。 context.SaveChanges() 会发生这种情况称呼。因此,您需要将其作为单独的调用,以便您能够实际更新当前实现无法处理的已编辑数据。

编辑:
你的评论让我意识到我看到的另一个问题。一个缺点是您在存储库中创建了一个数据上下文,这并不好。您确实应该让所有(或大部分)创建的存储库共享相同的数据上下文实例。

Entity Framework 会跟踪实体在哪个上下文中被跟踪,如果您尝试在一个上下文中使用另一个上下文更新实体,则会出现异常。当您开始编辑彼此相关的实体时,可能会出现这种情况。这也意味着您的 SaveChanges() call 不是事务性的,每个实体都在自己的事务中更新/添加/删除,这可能会变得困惑。

我在我的存储库中对此的解决方案是 DbContext在构造函数中传递到存储库。

关于entity-framework - EF4 CTP5 的存储库模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5066282/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com