2013-03-12 91 views
2

我試圖將以下SQL語句複製爲LINQ to Entities查詢(其中「PRODUCTS」是映射到實體的表)...注意IQueryable ...大部分是什麼我已經看到作爲解決方案轉換搜索參數,或將結果轉儲到IEnumerable然後繼續從那裏轉換。我正在處理數百萬條記錄,並且無法負擔將2億條記錄加載到內存中,只能再次通過它們進行篩選。我想,如果可能的話,在對數據庫的單個查詢中做到這一點。將字符串轉換爲實體在LINQ to Entities

select * 
from PRODUCTS 
where 
    MODEL_CODE = '65' and 
    CAST(SERIAL_NUMBER as int) > 927000 and 
    CAST(SERIAL_NUMBER as int) < 928000 

我曾嘗試以下...

int startSN, endSN; 
startSN = 9500 
endSN = 9500 

if (!int.TryParse(startSerialNumber, out startSN)) 
    throw new InvalidCastException("The start serial number was not a valid value"); 

if (!int.TryParse(endSerialNumber, out endSN)) 
    throw new InvalidCastException("The end serial number was not a valid value"); 

    IQueryable<PRODUCT> resultList = base.Context.PRODUCTS.Where(b => 
     (Convert.ToInt32(b.SERIAL_NUMBER) > startSN) && 
     (Convert.ToInt32(b.SERIAL_NUMBER) < endSN)).AsQueryable(); 

我已經嘗試了幾個事情其他版本類同這個沒有運氣。我也看過以下帖子也沒有運氣。

Convert string to int in an Entity Framework linq query and handling the parsing exception - 解決方案在轉換實體屬性之前將查詢轉換爲列表。

Convert string to Int in LINQ to Entities ? - 此問題只是轉換可以很容易地在LINQ to Entities語句之外完成的參數。我已經這樣做了參數。

LINQ to Entities StringConvert(double)' cannot be translated to convert int to string - 這個問題實際上是我的反向,試圖將int轉換爲字符串。 1)SqlFunctions沒有提供轉換爲一個int的函數。 2)最終解決方案是,在轉換/轉換值之前再次轉換爲IEnumerable。

任何人有任何其他的想法?我有點難住這個!

謝謝 摹

+2

這是LTE的一個非常討厭的限制。當然,你不能轉換爲'IEnumerable'並在內存中過濾1億條記錄。如果你不使用代碼優先,但基於EDMX的方法模型定義的函數可能是最好的解決方案(http://stackoverflow.com/questions/5754218/convert-string-to-int-in-ef-4- 0)。或者使用'base.Context.PRODUCTS.SqlQuery(string sql,params object []參數)'並傳入上面的SQL語句。 – Slauma 2013-03-12 23:47:33

+0

您可以嘗試使用視圖進行轉換(只需選擇所有行並將其轉換爲int列)。英孚不太喜歡看法,但這種簡單的東西可能適合你。 – 2013-03-13 03:03:57

+0

@Slauma對不起,我花了很長時間纔回來。建議使用「SqlQuery()」方法!雖然它打開了一些新的考慮因素,例如需要填充生成的實體集的導航屬性,但它讓我超越了這一步。我不確定是否有另一種方式來做到這一點,但這是迄今爲止最有前途的!無論如何,我想標記這是答案,但因爲這只是我不能做的評論。如果您將其作爲「答案」發佈,我很樂意將其標記爲此。否則,我會「回答我自己的問題」(當然有適當的認證)。再次感謝! – 2013-03-20 22:04:18

回答

0

如果不使用代碼第一,但基於EDMX方法模型定義的函數可能是最好的解決辦法:Convert String to Int in EF 4.0

或者您可以使用.. 。

base.Context.PRODUCTS.SqlQuery(string sql, params object[] parameters) 

...然後傳入您的問題中的原始SQL語句。

DbSet<T>.SqlQuery(...)作爲結果返回DbSqlQuery<T>。請記住這一點很重要,不是實施IQueryable<T>,但只有IEnumerable<T>。它的簽名是:

public class DbSqlQuery<TEntity> : IEnumerable<TEntity>, IEnumerable, IListSource 
    where TEntity : class 

所以,你可以進一步LINQ方法擴展這個結果,但它只是LINQ到將內存從SQL查詢中設置返回的結果來執行的對象。你可以而不是擴展它與LINQ到實體將在數據庫中執行。因此,將.Where篩選器添加到DbSqlQuery<T>對數據庫查詢以及從數據庫加載到內存中的數據集沒有任何影響。

這其實並不奇怪,因爲這將意味着,否則這部分表達式樹(從Where方法)必須轉換成SQL,然後合併成一個手寫的SQL語句,以便正確的新組成的SQL語句的結果和可以發送到數據庫。聽起來對我來說是一件相當艱鉅的任務。