2012-08-14 76 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