2014-09-11 77 views
1

說我有一個表table1使用字符串字段[ProductString]與值: 阿爾法,字母數字或數字:例如ABC,B4,U2,C 5,100,U1,U5, U6,U11使用一個NaturalSortComparer在LINQ where子句

我希望能夠採取WHERE子句,如「ProductString> = U5」,並通過這一個LINQ語句作爲字符串,因此評估

Table1.Where(t=> t.ProductString >= 'U5'); 

通常這會返回結果U5和U6。

然而,這個我希望能夠使用NaturalSortComparer不知何故,使返回的結果是U5,U6和U11。

我知道如何使用比較器在排序依據,由我希望能夠在舞臺在哪裏使用它。

+0

創建一個比較器的實例,然後使用它... – 2014-09-11 07:21:50

+0

@JeffMercado但謂詞將應用於服務器端。整個桌子都會被拿來,我認爲OP要遵循這個方法。恐怕存儲過程是必要的。 – 2014-09-11 07:24:11

+0

@pwas:好吧,不清楚源代碼是什麼。如果他在較早的查詢中使用了該比較器,那麼它可能不是數據庫。我們可以猜出所有我們想要的東西,但最終直到他澄清之後,這都無關緊要。 – 2014-09-11 07:26:56

回答

1

使用自然排序比較器:

var comparer = new NaturalComparer(); 
Table1.Where(t=> 
    comparer.Compare(t.ProductString, "U5") >= 0); 

意味着你的所有的產品串上格式化U%數量%,那麼,爲什麼不能濫用這個事實?

Table1.Where(t=> int.Parse(t.ProductString.Replace("U","")) >= 5); 

如果您使用LINQ到實體我不能肯定這將編譯到商店表達式(即是SQL知道如何處理這事 - 我想這應該)。

+2

它將被合併到ExpressionTree中,但是EF會失敗,並用'NotSupportedException'將它翻譯成SQL。 – 2014-09-11 07:26:21

+0

不能認爲字符串是這種格式。它可能只是Alpha或字母數字或數字:例如ABC,B4,U2,C 5,100。我將更新問題 – 2014-09-11 07:32:44

+0

使用「NaturalComparer」的解決方案是否適合您的賬單? – AlexanderBrevig 2014-09-11 07:44:51

0

如果你打算做這樣的搜索很多,那麼最好的辦法是在你的表格中添加兩個新字段,[ProductCode] & [ProductNumber],它將[ ProductString。

然後你比較變爲:

Table1.Where(t=> t.ProductCode == "U" && t.ProductNumer > 5); 
1

我有點困惑,因爲公認的答案,這個問題是否涉及到LINQ到實體與否。接受的答案似乎並不被認爲將在LINQ到實體環境中工作的解決方案,而是由OP關於這個問題的評論似乎證實,這是在數據庫上下文中執行。無論如何,這個答案是專門針對LINQ to Entities的。

我想在SQL Server這樣做會很難,但並非不可能。問題是,.NET知道什麼NaturalSortComparer是,但SQL Server(您想查詢最終發生)沒有這樣的概念。我能想到的最好的辦法將包括兩個部分:CREATE FUNCTION Naturalize(@val as nvarchar(max)) RETURNS nvarchar(1000)

  1. 在SQL服務器,這將使一個產品,是通過自然排序訂購創建UDF(用戶定義函數)。有一個非常酷的回答here創建一個圍繞CLR函數的UDF包裝來完成這一點。
  2. 接下來爲您的DbContext創建一個函數映射,將上面的UDF映射到可在EF查詢中針對DbContext調用的函數。事情是這樣的:

    [DbFunction("MyContext", "Naturalize")] 
    public static string Naturalize(this string value) 
    { 
        throw new NotSupportedException("This function can only be invoked from LINQ to Entities."); 
    } 
    

一旦你得到了這些適當的兩件,你可以很容易地使用這個新功能的實體,在查詢內部在比較使用Naturalized值比較字符串:

Table1.Where(t=> t.ProductString.Naturalize() >= "U5".Naturalize()); 

請記住,UDF將針對查詢中包含的每一行執行,即上述示例中的整個表。在將函數作爲子查詢應用之前,您需要確保將查詢精簡爲可管理的。或者你可能想嘗試在有問題的表上應用某種類型的基於UDF的索引。