2010-07-18 61 views
1

我有這個在我的查詢:方法 '包含布爾..' 有沒有支持轉換爲SQL

var results = (from urls in _context.Urls 
       join documents in _context.Documents on urls.UrlId equals documents.DocumentId 
       let words = (from words in _context.Words 
          join hits in _context.Hits on words.WordId equals hits.WordId 
          where hits.DocumentId == documents.DocumentId 
          select words.Text).AsEnumerable<string>() 

       where urls.ResolvedPath.Contains(breakedQuery, KeywordParts.Url, part) || 
         documents.Title.Contains(breakedQuery, KeywordParts.Title, part) || 
         documents.Keywords.Contains(breakedQuery, KeywordParts.Keywords, part) || 
         documents.Description.Contains(breakedQuery, KeywordParts.Description, part) || 
         words.Contains(breakedQuery, KeywordParts.Content, part) ... 

,幷包含擴展方法:

字符串

public static bool Contains(this string source, IEnumerable<string> values, KeywordParts valuePart, KeywordParts part) 
    { 
     if (!string.IsNullOrWhiteSpace(source)) 
      return source.Split(' ').AsEnumerable<string>().Contains(values, valuePart, part); 
     return false; 
    } 

枚舉的(主要方法)

public static bool Contains(this IEnumerable<string> source, IEnumerable<string> values, KeywordParts valuePart, KeywordParts part) 
    { 
     if (source != null && source.Count() > 0 && 
      values != null && values.Count() > 0 && 
      (part == KeywordParts.Anywhere || valuePart == part)) 
     { 
      foreach (var value in values) 
      { 
       var has = false; 
       var none = (value.StartsWith("-")); 
       string term = value.Replace("-", ""); 

       if (none) 
        has = source.Any(q => !q.Contains(value)); 
       else 
        has = source.Any(q => q.Contains(values)); 

       if (has) 
        return has; 
      } 
     } 
     return false; 
    } 

並使用Contains方法拋出異常NotSupportedException:方法的布爾Contains(String,IEnumerable`1 [String],KeywordParts,KeywordParts)'沒有支持的SQL轉換。

其實我想,如果有在租賃的指定條件

回答

3

你不能只寫你自己的方法,並從您的查詢表達式打電話給他們一個檢查每個索引文件 - 查詢翻譯根本不知道那是什麼方法的意思是做。

你可能會迫使where子句在.NET獲取的文件,也就是說,潛在的......雖然很明顯,這意味着獲取所有從數據庫中加入數據後執行。那會好嗎?

要做到這一點,你想要的東西,如:

var tmpQuery = (from urls in _context.Urls 
       join documents in _context.Documents 
       on urls.UrlId equals documents.DocumentId 
       let words = (from words in _context.Words 
          join hits in _context.Hits 
          on words.WordId equals hits.WordId 
          where hits.DocumentId == documents.DocumentId 
          select words.Text) 
       select new { urls, documents, words }; 

var query = from r in tmpQuery.AsEnumerable() 
      let urls = r.urls.ToList() 
      let words = r.words.ToList() 
      let documents = r.documents.ToList() 
      where urls.ResolvedPath.Contains(breakedQuery, 
              KeywordParts.Url, part) || 
       documents.Title.Contains(breakedQuery, 
             KeywordParts.Title, part) || 
       documents.Keywords.Contains(breakedQuery, 
              KeywordParts.Keywords, part) || 
       documents.Description.Contains(breakedQuery, 
               KeywordParts.Description, part) || 
       words.Contains(breakedQuery, KeywordParts.Content, part) 
      select new { urls, words, documents }; 
+0

非常好,謝謝你。你能給我一個方法來提高執行這個查詢的速度嗎?因爲你知道我正在開發非常基本的網絡搜索引擎,這是項目搜索部分的一部分。我檢索結果後,我想排序結果按選擇每個計算的速度。我將在單獨問題中發佈費率部分。 – Sadegh 2010-07-18 08:34:22

+0

這裏是我的問題http://stackoverflow.com/questions/3274897/simple-rating-algohritm-to-sorting-results-according-to-user-query – Sadegh 2010-07-18 08:58:53

3

我的理解,有人請糾正我,如果我錯了,問題是使用LINQ的擴展方法時到SQL擴展方法不像.NET代碼那樣執行,就像您在問題中使用的擴展方法一樣。

Linq to SQL擴展方法返回expression trees,Linq to SQL引擎然後解析並生成適當的SQL查詢以滿足表達式樹。

+0

是的,確切地說。在這種情況下,表達式樹會引用對'Contains'的調用,這是LINQ to SQL不知道的。 – 2010-07-18 07:40:19

+0

@Jon,感謝您的確認。 – 2010-07-18 07:53:02

3

實現此功能的另一種方法是在實現此功能的數據庫中編寫標量UDF。然後將該UDF拖放到LINQ-to-SQL設計器上,該設計器將允許您通過數據上下文訪問UDF。然後你可以使用的東西,如:

where _context.MyContains(documents.Title, breakedQuery, 
     KeywordParts.Title, part); 

和翻譯之後,將調用UDF(即WHERE dbo.MyContains(...)

1

這個一個有趣的事實是,我在運行.NET 4.0時,遇到下列錯誤我開發機器:

「Method'Boolean Contains(Int32)'has no supported translation to SQL。」

但是它在使用.NET 3.5的生產環境中運行得很好。

我猜測這是兩種環境之間版本的差異。然而,這是一個事實,我得到我的開發機器上的錯誤,但這些查詢運行的生產環境和LINQ查詢確實包含下面的代碼

var resultParts = (
       from l in tempDc.LineItems 
       from wo in tempDc.WorkOrders 
       where l.WorkOrderNumber == wo.WorkOrderNumber && 
        l.OrderID == wo.OrderID && 
        workOrderSerialNumbers.Contains(wo.SerialNumber) && 
        l.Part.PartTypeID == (int)PartTypes.InventoryPart 
       orderby l.OrderID_WO, l.WorkOrderNumber 
       select new PickReportPartDto() 
       {... 

哪裏workOrderSerialNumbers是一個列表。

0

這是可能的,如果你把你的枚舉並添加到.ToList()之前.Contains(r.SomeId)。我正在尋找這個錯誤,最初有一個ICollection與.Contains(r.SomeId)會拋出這個異常,但是做一個.ToList()解決了我的問題。希望這可以幫助別人。

注:我相信有一個表達式樹最大Linq2Sql ...所以一個大的列表可能會導致你另一個頭痛。只是一個想法和需要注意的事情。

這是LINQ2SQL代碼:

enter image description here

這是導致SQL: enter image description here

相關問題