2012-08-14 77 views
0

以前我會用這樣的排名我的搜索結果:搜索在SQL中的LINQ,MVC 3和實體排序框架

 --search product name 
    SELECT tblProduct.ProductID, 20 AS Ranking 
    FROM tblProduct 
    INNER JOIN tblManufacturer ON tblProduct.ManufacturerID=tblManufacturer.ManufacturerID 
    LEFT OUTER JOIN tblProductCollection ON tblProduct.CollectionID=tblProductCollection.CollectionID 
    WHERE tblManufacturer.Name + ISNULL(' ' + tblProductCollection.CollectionName, '') + ' ' + tblProduct.Name LIKE '%' + @term + '%' AND tblProduct.Active = 1 
    UNION ALL 

    --search product exact name 
    SELECT tblProduct.ProductID, 200 AS Ranking 
    FROM tblProduct WHERE Name = '%' + term AND tblProduct.Active = 1 
    UNION ALL 

這個例子說,如果你的搜索詞包含在名稱:20排名,如果你完全匹配名稱:200是排名。統一表格,排序(降序)和嘿presto!

我試圖在LINQ這一次做到這一點,我不確定如何去做這件事,說實話我不確定我以前的例子是最初做到這一點的最好方法。

所以,我有一個產品實體映射到我的數據庫,我已經在我的部分類稱爲SearchRanking添加一個屬性:

  var query = from p in db.Products 
        where p.Name.Contains(term) 
        select p; 

     var query2 = from p in db.Products 
        where p.Name.ToLower() == term 
        select p; 

不知怎的,我需要設置像這樣的屬性:

  var query = from p in db.Products 
        where p.Name.Contains(term) 
        select p, p.SearchRanking = 20; 

     var query2 = from p in db.Products 
        where p.Name.ToLower() == term 
        select p, p.SearchRanking = 200; 

我在正確的軌道上嗎?

回答

1

如果你想創建一個新的匿名類型,你可以這樣做:

var foundProducts = (from p in products 
           where p.Name.Contains(term) 
           select new Product 
            { 
             ProductId = p.ProductId, 
             Category = p.Category, 
             Brand = p.Brand, 
             SearchRanking = p.Name.ToLower() == term ? 200 : 20 
            }).OrderBy(s => s.SearchRanking).Take(20); 
+0

哦,我喜歡!我還有其他領域需要搜索,如類別,品牌和成本等。 被發現產品仍然是一種產品,所以我可以將我的視圖綁定到列表? – Smithy 2012-08-14 15:49:59

+0

我不確定你的產品類型是什麼 - 它是否內置SearchRanking?如果是這樣,您可以改爲投影到產品類型,並將所有屬性映射到那裏 – 2012-08-14 15:51:36

+0

是Product.SearchRanking存在。你是否打算使用Saj的答案? – Smithy 2012-08-14 16:00:54

1

我會做這樣的事情;

 var query = (from p in db.Products 
        where p.Name.Contains(term) 
        select p).ToList().ForEach(p => p.SearchRanking = 20); 

更有效的方法是:

 var query = (from p in db.Products 
        where p.Name.Contains(term) 
        select new Product 
        { 
         Id = p.Id, 
         //set the other props here 
         SearchRanking = 20 
        }).ToList(); 
+0

感謝您的回覆迅速,我基本上是循環的產品重新設置搜索排名,我會喜歡這樣的:select new {ID = p.ID,SearchRanking = 20},然後分組,然後最後在最後重新附加所有產品。從效率的角度考慮這個問題? – Smithy 2012-08-14 15:44:31

+0

我已經編輯了我的答案,第二種方法會更有效,並且您不會使用匿名類型。 – saj 2012-08-14 15:48:32