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# 使用存储库模式泛型的linq中的多个连接_C#_Entity Framework_Repository Pattern - Fatal编程技术网

C# 使用存储库模式泛型的linq中的多个连接

C# 使用存储库模式泛型的linq中的多个连接,c#,entity-framework,repository-pattern,C#,Entity Framework,Repository Pattern,我已经实现了一个存储库模式,其中包含一个对数据库执行CRUD操作的通用方法列表。这一点如下所示 public Repository(DbContext context) { _entities = context; _dbset = context.Set<T>(); } public IEnmerable<T> GetAll() { return _dbset.AsEnumerable&

我已经实现了一个存储库模式,其中包含一个对数据库执行CRUD操作的通用方法列表。这一点如下所示

public Repository(DbContext context)
    {
        _entities = context;
        _dbset = context.Set<T>();
    }

    public IEnmerable<T> GetAll()
    {

        return _dbset.AsEnumerable<T>();
    }
公共存储库(DbContext)
{
_实体=上下文;
_dbset=context.Set();
}
公共IEnmerableGetAll()
{
返回_dbset.AsEnumerable();
}
接下来,我有一个服务层,它实现了上述存储库类

卡车服务

在这个类中,为了使用存储库通用方法,我有以下代码:

private IRepository<Workers> _repositoryWorkers;
private IRepository<Jobs> _repositoryJobs;
private IRepository<Depts> _repositoryDepts;


public WorkerService(IRepository<Workers> repositoryWorkers, IRepository<Jobs> repositoryJobs, IRepository<Depts> repositoryDepts) 
{
  _repositoryWorkers = repositoryWorkers;
  _repositoryJobs = repositoryJobs;
  _repositoryDepts = repositoryDepts
}

// a query that makes multiple joins to retrieve data.
from h in _repositoryWorkers.GetAll()
join p in _repositoryJobs.GetAll() on h.Id equals p.Id
join q in _repositoryDepts.GetAll() on h.Id equals q.Id
私人电子储蓄(i u repository)工作者;;
私人电子储蓄(repositoryJobs);;
私人电子储蓄部门;
公共工作者服务(电子寄存工作者、电子寄存工作、电子寄存部门)
{
_repositoryWorkers=repositoryWorkers;
_repositoryJobs=repositoryJobs;
_repositoryDepts=repositoryDepts
}
//进行多个联接以检索数据的查询。
来自h in_repositoryWorkers.GetAll()
在h.Id等于p.Id的_repositoryJobs.GetAll()中加入p
在h.Id等于q.Id的_repositoryDepts.GetAll()中加入q
因此,在上面的TruckService类中,我实现了
IRepository
接口来继承泛型方法。在这个类中,我将进行一个查询,该查询执行多个连接以从数据库中获取数据。我得到的所有数据都是正确的,但我在某个地方读到,这种方法是:

混合和匹配基于存储库的查询和LINQ查询。相当地 与执行真正的联接相比,您要获取每个表的所有行 然后加入他们的记忆

因此,在这种情况下,是否有人可以建议我一种更好/更有效的方法来进行多次连接


*请注意,我是EF新手,这是我第一个使用存储库模式的项目

返回数据库中所有实体的IEnumerable集合是一个完美的方法。避免这样做,因为它会加载内存中的所有数据

您可以使用IQueryable,与IEnumerable不同,IQueryable在数据库中执行查询,您可以向其添加筛选,并且在具体化之前它不会实际执行查询并加载结果(如调用ToList()、FirstOrDefault()和其他一些函数)

外键、导航属性都是可用于在实体之间轻松导航的工具,并可为自己节省大量显式连接。您可以使用诸如“渴望加载”之类的方法来获取希望经常使用的导航属性。EF的主要目标之一是帮助您编写更少的代码。它为您节省了大量时间,也减少了您可能犯错误的地方(代码更少,错误更少,但在使用它时仍然要小心)


无论您是否想要使用存储库模式,这都是您的选择。有些人认为这是一种不必要的抽象,而不是EF上下文和集合已经提供的抽象。有些人认为这是将业务逻辑与数据库访问分离开来的必要条件。然而,在使用它之前,阅读很多关于它的内容是很重要的,特别是如果你是EF的新手。以下是他们文档中的内容。

我建议您从通用存储库返回
IQueryable
,以便以后可以在特定继承存储库中修改查询

但是,为了在泛型repository中包含
Include
,您可以将要包含的属性传递到GetAll方法
params Func[]
,然后将其聚合到查询中。 请参见下面的示例


但是,您将无法使用
然后使用include
。考虑返回<代码> iQueEdaby,以便以后可以修改查询。例如
GetJobsByWorkerId
\u repositoryJobs.GetAll()on h.Id等于p.Id
您实际上下载了整个表,只是为了在内存中查询。专业提示:当您刚刚学习实体框架时,不要遵循存储库模式。存储库模式可能适用于某些用例,但不适用于EF。作为额外的评论:当您在使用实体框架时看到
IEnumerable
时,您就做了错事。我的建议是:删除与存储库相关的任何内容,并直接、简单地使用EF-不要使用存储库反模式。使用
DbContext
和EF-model的全部功能,特别是导航属性、即时加载、投影查询等。创建我的DbContext实例,并使用该对象查询我的表。但现在不使用联接,而是使用导航属性。存储库是一种反模式,因为1)通常它只是
DbSet
周围的一个薄薄的(=无用的)包装,2)它妨碍LINQ查询组合,3)它引入了模棱两可的责任(“哪个存储库负责我的嵌套实体?”)有趣的是,他们从来没有展示过如何使用存储库模式编写
连接
,等等。。。您不能不公开
IQueryable
。MSDN示例应该与编写它们的人一起埋在地下,他们几乎总是使用糟糕的实践。返回
IQueryable
完全违背了拥有存储库的目的。拥有存储库的目的是抽象数据库层。如果
IQueryable
开始泄漏到其他层,则不能交换数据库实现,因为
IQueryable
特定于实体框架。