Linq to LLBLGen query problem

Posted by Jeroen Breuer on Stack Overflow See other posts from Stack Overflow or by Jeroen Breuer
Published on 2009-12-11T11:40:30Z Indexed on 2010/03/31 7:03 UTC
Read the original article Hit count: 573

Filed under:
|
|
|

Hello,

I've got a Stored Procedure and i'm trying to convert it to a Linq to LLBLGen query. The query in Linq to LLBGen works, but when I trace the query which is send to sql server it is far from perfect.

This is the Stored Procedure:

ALTER PROCEDURE [dbo].[spDIGI_GetAllUmbracoProducts] 
-- Add the parameters for the stored procedure.
@searchText nvarchar(255),
@startRowIndex int,
@maximumRows int,
@sortExpression nvarchar(255) AS BEGIN

SET @startRowIndex = @startRowIndex + 1
SET @searchText = '%' + @searchText + '%'

-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;	

-- This is the query which will fetch all the UmbracoProducts.
-- This query also supports paging and sorting.
WITH UmbracoOverview As 
(
	SELECT		ROW_NUMBER() OVER(
		ORDER BY 
		CASE 
			WHEN @sortExpression = 'productName' THEN umbracoProduct.productName 
			WHEN @sortExpression = 'productCode' THEN umbracoProduct.productCode			
		END ASC,
		CASE 
			WHEN @sortExpression = 'productName DESC' THEN umbracoProduct.productName 
			WHEN @sortExpression = 'productCode DESC' THEN umbracoProduct.productCode			
		END DESC ) 
		AS row_num, umbracoProduct.umbracoProductId, umbracoProduct.productName, umbracoProduct.productCode
	FROM         umbracoProduct INNER JOIN
                  product ON umbracoProduct.umbracoProductId = product.umbracoProductId
	WHERE		(umbracoProduct.productName LIKE @searchText 
	OR			umbracoProduct.productCode LIKE @searchText
	OR			product.code LIKE @searchText
	OR			product.description LIKE @searchText
	OR			product.descriptionLong LIKE @searchText
	OR			product.unitCode LIKE @searchText)
)

SELECT		UmbracoOverview.UmbracoProductId, UmbracoOverview.productName, UmbracoOverview.productCode 
FROM		UmbracoOverview 
WHERE		(row_num >= @startRowIndex 
AND			row_num < (@startRowIndex + @maximumRows))


-- This query will count all the UmbracoProducts.
-- This query is used for paging inside ASP.NET.
SELECT		COUNT (umbracoProduct.umbracoProductId) AS CountNumber
FROM        umbracoProduct INNER JOIN
				product ON umbracoProduct.umbracoProductId = product.umbracoProductId
WHERE		(umbracoProduct.productName LIKE @searchText 
OR			umbracoProduct.productCode LIKE @searchText
OR			product.code LIKE @searchText
OR			product.description LIKE @searchText
OR			product.descriptionLong LIKE @searchText
OR			product.unitCode LIKE @searchText) END

This is my Linq to LLBLGen query:

using System.Linq.Dynamic;

        var q = (
                    from up in MetaData.UmbracoProduct
                    join p in MetaData.Product on up.UmbracoProductId equals p.UmbracoProductId
                    where up.ProductCode.Contains(searchText) ||
                        up.ProductName.Contains(searchText) ||
                        p.Code.Contains(searchText) ||
                        p.Description.Contains(searchText) ||
                        p.DescriptionLong.Contains(searchText) ||
                        p.UnitCode.Contains(searchText)
                    select new UmbracoProductOverview
                    {
                        UmbracoProductId = up.UmbracoProductId,
                        ProductName = up.ProductName,
                        ProductCode = up.ProductCode
                    }
                ).OrderBy(sortExpression);

//Save the count in HttpContext.Current.Items. This value will only be saved during 1 single HTTP request.
HttpContext.Current.Items["AllProductsCount"] = q.Count();

//Returns the results paged.
return q.Skip(startRowIndex).Take(maximumRows).ToList<UmbracoProductOverview>();

This is my Initial expression to process:

value(SD.LLBLGen.Pro.LinqSupportClasses.DataSource`1[Eurofysica.DB.EntityClasses.UmbracoProductEntity]).Join(value(SD.LLBLGen.Pro.LinqSupportClasses.DataSource`1[Eurofysica.DB.EntityClasses.ProductEntity]), up => up.UmbracoProductId, p => p.UmbracoProductId, (up, p) => new <>f__AnonymousType0`2(up = up, p = p)).Where(<>h__TransparentIdentifier0 => (((((<>h__TransparentIdentifier0.up.ProductCode.Contains(value(Eurofysica.BusinessLogic.BLL.Controllers.UmbracoProductController+<>c__DisplayClass1).searchText) || <>h__TransparentIdentifier0.up.ProductName.Contains(value(Eurofysica.BusinessLogic.BLL.Controllers.UmbracoProductController+<>c__DisplayClass1).searchText)) || <>h__TransparentIdentifier0.p.Code.Contains(value(Eurofysica.BusinessLogic.BLL.Controllers.UmbracoProductController+<>c__DisplayClass1).searchText)) || <>h__TransparentIdentifier0.p.Description.Contains(value(Eurofysica.BusinessLogic.BLL.Controllers.UmbracoProductController+<>c__DisplayClass1).searchText)) || <>h__TransparentIdentifier0.p.DescriptionLong.Contains(value(Eurofysica.BusinessLogic.BLL.Controllers.UmbracoProductController+<>c__DisplayClass1).searchText)) || <>h__TransparentIdentifier0.p.UnitCode.Contains(value(Eurofysica.BusinessLogic.BLL.Controllers.UmbracoProductController+<>c__DisplayClass1).searchText))).Select(<>h__TransparentIdentifier0 => new UmbracoProductOverview() {UmbracoProductId = <>h__TransparentIdentifier0.up.UmbracoProductId, ProductName = <>h__TransparentIdentifier0.up.ProductName, ProductCode = <>h__TransparentIdentifier0.up.ProductCode}).OrderBy( => .ProductName).Count()

Now this is how the queries look like that are send to sql server:

Select query:

Query: SELECT [LPA_L2].[umbracoProductId] AS [UmbracoProductId], [LPA_L2].[productName] AS [ProductName], [LPA_L2].[productCode] AS [ProductCode] FROM ( [eurofysica].[dbo].[umbracoProduct] [LPA_L2]  INNER JOIN [eurofysica].[dbo].[product] [LPA_L3]  ON  [LPA_L2].[umbracoProductId] = [LPA_L3].[umbracoProductId]) WHERE ( ( ( ( ( ( ( ( [LPA_L2].[productCode] LIKE @ProductCode1) OR ( [LPA_L2].[productName] LIKE @ProductName2)) OR ( [LPA_L3].[code] LIKE @Code3)) OR ( [LPA_L3].[description] LIKE @Description4)) OR ( [LPA_L3].[descriptionLong] LIKE @DescriptionLong5)) OR ( [LPA_L3].[unitCode] LIKE @UnitCode6))))

Parameter: @ProductCode1 : String. Length: 2. Precision: 0. Scale: 0. Direction: Input. Value: "%%". Parameter: @ProductName2 : String. Length: 2. Precision: 0. Scale: 0. Direction: Input. Value: "%%". Parameter: @Code3 : String. Length: 2. Precision: 0. Scale: 0. Direction: Input. Value: "%%". Parameter: @Description4 : String. Length: 2. Precision: 0. Scale: 0. Direction: Input. Value: "%%". Parameter: @DescriptionLong5 : String. Length: 2. Precision: 0. Scale: 0. Direction: Input. Value: "%%". Parameter: @UnitCode6 : String. Length: 2. Precision: 0. Scale: 0. Direction: Input. Value: "%%".

Count query:

Query: SELECT TOP 1 COUNT(*) AS [LPAV_] FROM (SELECT [LPA_L2].[umbracoProductId] AS [UmbracoProductId], [LPA_L2].[productName] AS [ProductName], [LPA_L2].[productCode] AS [ProductCode] FROM ( [eurofysica].[dbo].[umbracoProduct] [LPA_L2]  INNER JOIN [eurofysica].[dbo].[product] [LPA_L3]  ON  [LPA_L2].[umbracoProductId] = [LPA_L3].[umbracoProductId]) WHERE ( ( ( ( ( ( ( ( [LPA_L2].[productCode] LIKE @ProductCode1) OR ( [LPA_L2].[productName] LIKE @ProductName2)) OR ( [LPA_L3].[code] LIKE @Code3)) OR ( [LPA_L3].[description] LIKE @Description4)) OR ( [LPA_L3].[descriptionLong] LIKE @DescriptionLong5)) OR ( [LPA_L3].[unitCode] LIKE @UnitCode6))))) [LPA_L1]

Parameter: @ProductCode1 : String. Length: 2. Precision: 0. Scale: 0. Direction: Input. Value: "%%". Parameter: @ProductName2 : String. Length: 2. Precision: 0. Scale: 0. Direction: Input. Value: "%%". Parameter: @Code3 : String. Length: 2. Precision: 0. Scale: 0. Direction: Input. Value: "%%". Parameter: @Description4 : String. Length: 2. Precision: 0. Scale: 0. Direction: Input. Value: "%%". Parameter: @DescriptionLong5 : String. Length: 2. Precision: 0. Scale: 0. Direction: Input. Value: "%%". Parameter: @UnitCode6 : String. Length: 2. Precision: 0. Scale: 0. Direction: Input. Value: "%%".

As you can see no sorting or paging is done (like in my Stored Procedure). This is probably done inside the code after all the results are fetched. This costs a lot of performance! Does anybody know how I can convert my Stored Procedure to Linq to LLBLGen the proper way?

© Stack Overflow or respective owner

Related posts about llblgenpro

Related posts about LINQ