最优LINQ过滤方法

时间:2017-08-02 08:23:55

标签: c# asp.net asp.net-mvc linq

我在LINQ中过滤了项目列表的结果,我已经看到了两种方法,并且想知道哪个(如果有的话)更好。一个是我在使用Intellisense后想出的方法,另一个是来自ASP.NET MVC教程(found here

我的方法

    // GET: ProductVersions
    public ActionResult Index(string productName)
    {
        var productVersions = db.ProductVersions.Include(p => p.LicenceVersion).Include(p => p.Product);

        if (!string.IsNullOrEmpty(productName))
        {
            productVersions = productVersions.Where(s => s.Product.Name == productName);
        }

        return View(productVersions.ToList());
    }

教程方法

public ActionResult Index(string movieGenre)
{
    var GenreLst = new List<string>();

    var GenreQry = from d in db.Movies
                   orderby d.Genre
                   select d.Genre;

    GenreLst.AddRange(GenreQry.Distinct());
    ViewBag.movieGenre = new SelectList(GenreLst);

    var movies = from m in db.Movies
                 select m;

    if (!string.IsNullOrEmpty(movieGenre))
    {
        movies = movies.Where(x => x.Genre == movieGenre);
    }

    return View(movies);
}

我的问题

  1. 性能是否存在显着差异,尤其是第二种选择非常详细
  2. 使用我的方法
  3. 是否存在我缺少的风格约定
  4. 使用第二种方法还有其他可能的优势吗
  5. 〜编辑〜

    原来我需要ViewBag数据才能在前端填充下拉过滤器(更多可惜),所以我的实际代码计算如下:

            // GET: ProductVersions
            public ActionResult Index(string productName)
            {
                //Get list of product names to filter by
                var ProductLst = new List<string>();
                var ProductQry = from pv in db.ProductVersions
                                 orderby pv.Product.Name
                                 select pv.Product.Name;
    
                ProductLst.AddRange(ProductQry.Distinct());
                ViewBag.productName = new SelectList(ProductLst);
    
                //Populate product versions
                var productVersions = db.ProductVersions.Include(p => p.LicenceVersion).Include(p => p.Product);
    
                //Filter by product name
                if (!string.IsNullOrEmpty(productName))
                {
                    productVersions = productVersions.Where(s => s.Product.Name == productName);
                }
    
                return View(productVersions.ToList());
            }
    

3 个答案:

答案 0 :(得分:2)

示例代码的最后一部分与您的问题相当 - 类型列表是UI中的其他代码中没有的内容,这很好。所以我们要比较的是:

var productVersions = db.ProductVersions.Include(p => p.LicenceVersion)
     .Include(p => p.Product);

if (!string.IsNullOrEmpty(productName))
{
    productVersions = productVersions.Where(s => s.Product.Name == productName);
}

return View(productVersions.ToList());

VS

var movies = from m in db.Movies
             select m;

if (!string.IsNullOrEmpty(movieGenre))
{
    movies = movies.Where(x => x.Genre == movieGenre);
}

return View(movies);

这几乎完全相同 - 主要区别在于您的代码中的额外包含,如果您需要它们,这很好。

它们具有可比性,在比较方面没有任何相关内容。

我个人更喜欢你的例子中的ToList(),因为它强制数据在控制器而不是视图中实现。与此相反的是,视图具有可查询允许视图进一步组合。我不希望我的视图撰写查询,但这是一个风格点。

答案 1 :(得分:1)

您提供的代码示例有很多差异,但假设您询问扩展方法语法与查询语法,我认为答案如下:

  1. 表现没有差异。编译器以相同的方式处理样本。
  2. 你不缺少任何风格约定。我经常发现链接扩展方法更具可读性和可维护性
  3. 当您想要利用多个范围变量时,可能会出现使用查询语法的情况。看看这个答案: LINQ - Fluent and Query Expression - Is there any benefit(s) of one over other?

答案 2 :(得分:0)

我知道你使用了Eager Loading。如果您的模型不那么复杂,我认为没有必要进行EagerLoading。 为此使用Layz加载;我也试着重构你的代码。看看我的代码风格和codeLine数:)这可以帮助你特别大的类:) H

http://www.entityframeworktutorial.net/EntityFramework4.3/lazy-loading-with-dbcontext.aspx

在以下链接中,您可以获得详细信息。

示例类也可以翻译linke

public ActionResult Index(string productName)
{
   if(string.IsNullOrEmpty(productName)) return View(new List<ProductVersions>());
   return View(db.ProductVersions.Where(s => s.Product.Name == productName).ToList());
}

最后,您的exp和教程&#34;之间的错误是错误的。因为ViewModel在TutorialExp中使用过。这对于防止客户端直接使用DbCon对象非常有用。在我看来

using(var db=new DbEntities())  

是本教程所必需的。