Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/269.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# 从控制器查询列表<;T>;从存储库中获取,是否增加耦合?_C#_Entity Framework_Asp.net Mvc 3_Repository Pattern_Loose Coupling - Fatal编程技术网

C# 从控制器查询列表<;T>;从存储库中获取,是否增加耦合?

C# 从控制器查询列表<;T>;从存储库中获取,是否增加耦合?,c#,entity-framework,asp.net-mvc-3,repository-pattern,loose-coupling,C#,Entity Framework,Asp.net Mvc 3,Repository Pattern,Loose Coupling,我有一个用C#编码的ASP.NET MVC应用程序。应用程序的结构如下: 控制器 存储库 LINQ到实体(实体框架) 看法 我使用存储库(\u ProductRep)查询LINQ to实体,并将实际实体或列表,而不是IQueriables 我想在我有更多疑问的情况下得到一些帮助。我有以下代码: List<Monthly_Report> lproduct_monthlyReport = _ProductRep.GetArchiveReport(product.Prod_ID, lmon

我有一个用C#编码的ASP.NET MVC应用程序。应用程序的结构如下:

  • 控制器

  • 存储库

  • LINQ到实体(实体框架)

  • 看法

  • 我使用存储库(
    \u ProductRep
    )查询LINQ to实体,并将实际实体或
    列表
    ,而不是
    IQueriables

    我想在我有更多疑问的情况下得到一些帮助。我有以下代码:

    List<Monthly_Report> lproduct_monthlyReport = _ProductRep.GetArchiveReport(product.Prod_ID, lmonth, lyear);
    
    其中
    litemList
    是产品可能拥有的所有项目的列表

    我想知道这个解决方案是否明智地增加了耦合(并且违反了规则),或者它是可以接受的,因为我实际上查询的是
    列表
    ,而不是
    IQueriable
    。如果我错了,请纠正我,但我猜由于列表不需要访问EF DataContext,所以控制器和EF之间没有耦合

    如果我错了,我能想到的唯一解决方案是用存储库方法替换查询(我仍然需要实现):

    但是,使用此解决方案时,存储库在每个循环周期中使用4个条件进行一次查询,而在以前的解决方案中,存储库仅使用一个条件进行查询

    你能在这个问题上给我一些启发吗?谢谢

    PS:我需要循环中的两个变量
    lproduct\u monthlyReport
    lproductItem\u monthlyReport
    ,我不能只使用其中一个


    PPS:我知道我应该在控制器和存储库之间有一个业务服务层,这是我的下一步。

    我可能会有这样的函数
    getArchiverReport(int-prodID,int-lmonth,int-lyear,IEnumerable-itemIDs)
    在查询中执行itemIDs.Contains(tbl.ID)

    var SelectedReports = _ProductRep.GetArchiveReport(product.Prod_ID, lmonth, lyear, litemList.Select(item => item.Item_ID));
    foreach(var prodItem in SelectedReports)
    {
      //Do code
    }
    

    从存储库返回列表会给您带来糟糕的性能,因为您会丢失延迟执行行为。基本上,您的存储库将把每一条记录(而不是相关的实体)检索到内存中,并将它们转换成一个列表,然后在内存中进行处理。如果您想访问一个相关的实体,它将需要另一个数据库。如果您坚持使用IEnumerable(或IQueryable),那么您将对客户机隐藏实体框架行为的细微差别,但仍然可以获得延迟加载和延迟执行等优点

    现在忽略存储库的细节,如果您这样做:

    List<Product> products = MyEntities.Products.ToList();
    
    Product product1 = products.Single(p => p.Id = 1);
    
    List products=myenties.products.ToList();
    product1=products.Single(p=>p.Id=1);
    
    它的表现将比这糟糕得多:

    IEnumerable<Product> products = MyEntities.Products;
    
    Product product1 = products.Single(p => p.Id = 1);
    
    IEnumerable products=MyEntities.products;
    product1=products.Single(p=>p.Id=1);
    
    第一个将在没有WHERE子句的数据库中执行SELECT,然后为每个结果实例化.Net对象,然后在内存列表中查询该对象。第二个将不执行任何操作,直到您访问product1上的属性,并在此时发出一个数据库命令以仅检索1产品,并仅实例化该1产品


    对于较小的数据集,2之间的差异可能不明显,但随着数据集变大,这将变得越来越糟糕。加入一个连接的实体(或者更糟糕的实体集合),您可能会得到数千个数据库点击,如果您坚持使用IEnumerable,您将得到1。

    我不同意这一点。我建议从DAL返回列表。例如调用products.Single(p=>p.Id=1);在没有列表的循环中,每次迭代都会导致一个DB调用。@RichardW1001:谢谢你的回答。存储库模式规定存储库只返回实际的实体。然后,你应该有足够的灵活性来理解在哪里可以放松特定的处方。但是,通过返回IQuerable(或IEnumerable),您需要打开LINQtoSQL上下文,而我使用using指令打开数据上下文(仅在指令区域内有效)是的,这将非常可怕。。。但这和我说的正好相反!我的意思是,如果要从存储库返回项目集合,请将其保留为IEnumerable或IQueryable,而不是or列表,以便保持延迟执行。我想指出的一点是,如果您返回一个列表,那么数据库调用已经完成,并且只能在内存中进行优化。但是,如果返回IEnumerable,则可以在进行数据库调用之前向查询中添加更多筛选器,同时保持EF的分离和忽略。如果在DAL函数中(正确)处理了DataContext,则不能将其保留为IEnumerable或IQueryable。另外,我不建议从DAL发送Linq实体,而是使用DTO'sAm I遗漏了一些东西-为什么这么快就要处理上下文?你明白上下文和连接是完全分开的吗?创建一个新的上下文会有相当大的开销?您不应该让他们坐在那里,但您肯定应该让他们坐在那里足够长的时间,以便以最有效的方式正确地检索数据!建议您启动一个快速控制台应用程序,并排使用这两种方法,使用跟踪/探查器查看每种方法的数据库活动-这将比文字解释得更好。谢谢您的回答。但是,这些函数的用途是什么?使用litemList.Select(item=>item.item_ID)实际上可以进行投影。请你更好地解释一下你的解决办法好吗?
    List<Product> products = MyEntities.Products.ToList();
    
    Product product1 = products.Single(p => p.Id = 1);
    
    IEnumerable<Product> products = MyEntities.Products;
    
    Product product1 = products.Single(p => p.Id = 1);