2013-03-12 141 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语句的结果和可以发送到数据库。听起来对我来说是一件相当艰巨的任务。

相关问题