Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.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
LINQ到SQL查询优化_Linq_Linq To Sql - Fatal编程技术网

LINQ到SQL查询优化

LINQ到SQL查询优化,linq,linq-to-sql,Linq,Linq To Sql,我主要在java上工作,并且是LINQ的新手,所以我需要一些关于这个查询性能的建议 1. Products --> ProductID | Name | Price | VendorID 2. Category --> CategoryID | Label 3. SubCategory--> SubCategoryID | Label | ParentID 4. Pro

我主要在java上工作,并且是LINQ的新手,所以我需要一些关于这个查询性能的建议

1. Products  -->                   ProductID | Name | Price | VendorID
2. Category  -->                   CategoryID | Label
3. SubCategory-->                  SubCategoryID | Label | ParentID
4. Product_SubCategory_Mapping-->  ProductID | SubCategoryID 
5. Vendor     -->                  VendorID | VendorName
我想从product表中为任何给定子类别选择所有产品及其供应商。下面的查询可以正常工作吗?或者它需要任何优化

var list =  (from p in Products 
             join cat in Product_SubCategory_Mapping 
             on p.UserId equals cat.UserId 
             join sub in SubCategories 
             on cat.SubCategoryId equals sub.SubCategoryId
             where sub.CategoryId == 19 && CustomFunction(p.ID) > 100 
             select new { p, p.Vendor, trend = CustomFunction(p.ID) })
             .Skip((pageNum - 1) * pageSize)
             .Take(pageSize);
我将创建一个自定义类,该类将匹配查询结果

  • 在这种情况下,创建视图/存储过程是更好的方案吗
  • CustomFunction(p.ID)>100是否可以命名,这样函数就不会被调用两次?它是数据库中的自定义函数
  • 对于分页是否会跳过并执行良好
    您的思路是正确的,但是LINQ to SQL无法理解
    CustomFunction()
    ,因此您需要使用
    AsEnumerable()
    切换到LINQ to对象,然后才能调用它。您还可以使用
    let
    捕获
    CustomFunction()
    的结果一次,以便在查询中的其他位置使用:

    var listFromSql = from p in Products
                      join cat in Product_SubCategory_Mapping
                        on p.UserId equals cat.UserId
                      join sub in SubCategories
                        on cat.SubCategoryId equals sub.SubCategoryId
                      where sub.CategoryId == 19
                      select p;
    
    var list = from p in listFromSql.AsEnumerable()
               let trend = CustomFunction(p.ID)
               where trend > 100
               select new { p, p.Vendor, trend };
    
    更新:回答您列出的问题:

  • 这是一个相对简单的SQL,因此L2SQL生成的内容应该很好。您可以使用L2SQL日志记录或SQL探查器来确认SQL是否足够好
  • 请参见上面的
    let
  • IQueryable
    上的
    Skip()
    Take()
    (如上面的
    listFromSql
    )将转换为适当的SQL,从而限制通过线路发送的结果集<在
    IEnumerable
    上的code>Skip()和
    Take()
    只需枚举序列以获得请求的结果,但对SQL返回的完整结果集进行操作

  • 您的思路是正确的,但是LINQ to SQL无法理解
    CustomFunction()
    ,因此您需要使用
    AsEnumerable()
    切换到LINQ to对象,然后才能调用它。您还可以使用
    let
    捕获
    CustomFunction()
    的结果一次,以便在查询中的其他位置使用:

    var listFromSql = from p in Products
                      join cat in Product_SubCategory_Mapping
                        on p.UserId equals cat.UserId
                      join sub in SubCategories
                        on cat.SubCategoryId equals sub.SubCategoryId
                      where sub.CategoryId == 19
                      select p;
    
    var list = from p in listFromSql.AsEnumerable()
               let trend = CustomFunction(p.ID)
               where trend > 100
               select new { p, p.Vendor, trend };
    
    更新:回答您列出的问题:

  • 这是一个相对简单的SQL,因此L2SQL生成的内容应该很好。您可以使用L2SQL日志记录或SQL探查器来确认SQL是否足够好
  • 请参见上面的
    let
  • IQueryable
    上的
    Skip()
    Take()
    (如上面的
    listFromSql
    )将转换为适当的SQL,从而限制通过线路发送的结果集<在
    IEnumerable
    上的code>Skip()和
    Take()
    只需枚举序列以获得请求的结果,但对SQL返回的完整结果集进行操作

  • 因为CustomFunction是数据库中的ScalarFunction,所以LINQ to SQL应该能够有效地评估它。您可能希望使用LET提取一次该值,但请检查生成的SQL和查询执行计划,看看它是否提供了任何改进,或者SQL Server是否在内部自动进行了适当的优化

    var list =  (from p in Products  
                 join cat in Product_SubCategory_Mapping  
                 on p.UserId equals cat.UserId  
                 join sub in SubCategories  
                 on cat.SubCategoryId equals sub.SubCategoryId
                 let trend = CustomFunction(p.ID) 
                 where sub.CategoryId == 19 && trend > 100  
                 select new { p, p.Vendor, trend }) 
                 .Skip((pageNum - 1) * pageSize) 
                 .Take(pageSize); 
    
    如果元素之间存在关联,则可能希望使用它们而不是联接。它不会改变生成的查询(很多),但可能更易于维护,因为连接是由模型中建立的关联抽象出来的

    var list = (from p in Products
               from cat in p.Product_SubCategory_Mappings
               let trend = CustomFunction(p.ID)
               where cat.SubCategory.CategoryId == 19 && trend > 100
               select new { Product = p, p.Vendor, trend})
               .Skip(pageNum - 1) * pageSize)
               .Take(pageSize);
    

    因为CustomFunction是数据库中的ScalarFunction,所以LINQ to SQL应该能够有效地评估它。您可能希望使用LET提取一次该值,但请检查生成的SQL和查询执行计划,看看它是否提供了任何改进,或者SQL Server是否在内部自动进行了适当的优化

    var list =  (from p in Products  
                 join cat in Product_SubCategory_Mapping  
                 on p.UserId equals cat.UserId  
                 join sub in SubCategories  
                 on cat.SubCategoryId equals sub.SubCategoryId
                 let trend = CustomFunction(p.ID) 
                 where sub.CategoryId == 19 && trend > 100  
                 select new { p, p.Vendor, trend }) 
                 .Skip((pageNum - 1) * pageSize) 
                 .Take(pageSize); 
    
    如果元素之间存在关联,则可能希望使用它们而不是联接。它不会改变生成的查询(很多),但可能更易于维护,因为连接是由模型中建立的关联抽象出来的

    var list = (from p in Products
               from cat in p.Product_SubCategory_Mappings
               let trend = CustomFunction(p.ID)
               where cat.SubCategory.CategoryId == 19 && trend > 100
               select new { Product = p, p.Vendor, trend})
               .Skip(pageNum - 1) * pageSize)
               .Take(pageSize);
    

    忘记提到CustomFunction是数据库中的自定义函数。LINQ的陈述仍然无法识别它吗?我在LINQPAD中使用过它,我从来没有在自定义函数中使用过L2SQL——如果它在LINQPAD中工作,我希望它在任何地方都能工作。它与
    let
    一起工作吗?是的,我是这样使用它的:(从u中的用户加入u.UserId上的业务类别中的cat.UserId等于cat.UserId加入cat.subcategory上的子类别中的sub.subcategory id等于sub.subcategory id let trend=calculatedInstance(u.Zipcode,“07306”)其中sub.CategoryId==19&&trendLINQ to SQL支持标量函数和表值函数。EF在这里有更多限制。忘了提到CustomFunction是数据库中的自定义函数。LINQ语句仍然无法识别它?我使用LINQPAD,它工作得很好。我从未将L2SQL用于自定义函数-如果它在LINQP中工作的话AD我希望它在任何地方都能工作。它与
    let
    一起工作吗?是的,我这样使用它:(从u中的用户在u.UserId上加入业务类别中的cat.UserId在cat.subcategory上加入子类别中的sub.subcategory id等于sub.subcategory id let trend=calculatedInstance(u.Zipcode,“07306”)其中sub.CategoryId==19&&trendLINQ to SQL支持标量和表值函数。EF在这里有更多限制。请简要说明一下(因为我的LINQ技能很弱,我无法提供任何有用的建议来实际回答您的问题)…但我忍不住注意到,您的products表有一个ProductID列,而其他两个表只有一个ID列。我猜这些列代表一个主键字段(可能也代表一个标识字段)如果是这样,您可能需要考虑在所有表中使名称一致:IE、Realy.CyryYID或Studio.StudioD>产品。ID。对于供应商和子类别,同意。谢谢建议。我更改了名称。我的实际数据库有正确的名称。只是一个快速注释。(因为我的LINQ技能很弱,我无法提供任何有用的建议来回答你的问题)…但我不能不