entity framework/ Linq EXpression从string转换为int
我有一个像这样的expression:
var values = Enumerable.Range(1,2); return message => message.Properties.Any( p => p.Key == name && int.Parse(p.Value) >= values[0] && int.Parse(p.Value) <= values[1]);
这编译好,但是当它碰到数据库时,它会抛出exception'LINQ to Entities does not recognize the method 'Int32 Parse(System.String)' method, and this method cannot be translated into a store expression '
如果我不做parsing和值是一个string[]
我不能然后使用>=
和<=
操作符的string。
p.Value
是一个保存各种值的string,但在这种情况下它是int
有没有一种方法,我可以查询数据库做这种之间的语句?
正如其他人在评论中指出的,你必须parsing这个值的事实应该是一个红旗,你应该在你的数据库中使用不同的数据types。
幸运的是,通过强制查询由LINQ执行到对象而不是LINQ to Entities来解决这个问题。 不幸的是,这意味着可能会将大量的数据读入内存
编辑
根据您的其他意见,“价值”列中的值不保证是一个数字。 因此,您必须尝试将该值转换为数字,然后根据该转换的失败/成功来处理事务:
return message .Properties .AsEnumerable() .Any(p => { var val = 0; if(int.TryParse(p.Value, out val)) { return p.Key == name && val >= values[0] && val <= values[1]) } else { return false; } );
编辑2
你可能实际上能够在数据库中脱身。 我不确定这是否会起作用,但给它一个镜头:
return message.Properties .Where(p => p.Key == name && SqlFunctions.IsNumeric(p.Value) > 0) .Any(p => Convert.ToInt32(p.Value) >= values[0] && Convert.ToInt32(p.Value) <= values[1]);
尽我讨厌这个答案。 实际的答案是你不能轻易做到这一点。 这将是一个真正的痛苦。 我看到很多错误的答案和很多答案,有人说你应该只是把你的数据库字段放在正确的types。 没有帮助。
这个问题类似于http://social.msdn.microsoft.com/Forums/en-US/ce9652e3-5450-44c4-a9bd-586b4c4e6a27/convert-string-to-int-in-whereorderby-is-it-possible ?论坛= adodotnetentityframework
有几种可能性取决于你正在使用什么types的EF。
1.您正在使用EDMX文件。
(不先编码或反向工程编码)。 你可以使用类似于( LINQ to Entities不能识别“Double Parse(System.String)”方法的方法,而且这个方法不能被转换成存储expression式 )
[EdmFunction("PlusDomain", "ParseDouble")] public static double ParseDouble(string stringvalue) { /// This method exists for use in LINQ queries, /// as a stub that will be converted to a SQL CAST statement. return System.Double.Parse(stringvalue); }
并在你的EDMX中映射
> <Function Name="ParseDouble" ReturnType="Edm.Double"> > <Parameter Name="stringvalue" Type="Edm.String" /> > <DefiningExpression> > cast(stringvalue as Edm.Double) > </DefiningExpression> > </Function>
2.如果您在EF> = 4.1中首先使用代码。
你完了。 微软并不认为可以将任何这样的function添加到SqlFunctions中。 你可以期望的最好的方法是在你的数据库中添加一个标量SQL函数,并且(可能)试图将它映射到你的上下文中。 微软在代码中没有看到任何这样的事情。 幸运的是,他们并没有完全阻止这样的事情。 Fluent APIfunction强大。
这将是这样的事情:
你可以像这样调用函数或存储过程: 首先用ef4.1代码定义标量函数? 或http://weblogs.asp.net/dwahlin/using-entity-framework-code-first-with-stored-procedures-that-have-output-parameters like:
var outParam = new SqlParameter(“overHours”,SqlDbType.Int); outParam.Direction = ParameterDirection.Output;
var data = context.Database.ExecuteSqlCommand(“dbo.sp_getNumberJobs @overHours OUT”,outParam); int numJobs =(int)outParam.Value;
但是为了让它们实际上融入到LinQ中,你需要更多这样的东西:
https://codefirstfunctions.codeplex.com/使用http://www.nuget.org/packages/EntityFramework.CodeFirstStoreFunctions它将SQL函数映射到上下文中,但是这使用了一个仅用于;.NET 4.5的外部库http:// blog.3d-logic.com/2014/04/09/support-for-store-functions-tvfs-and-stored-procs-in-entity-framework-6-1/
或者您可以尝试使用类似的方法手动执行相同的操作:
entity framework6代码第一个函数映射或
https://entityframework.codeplex.com/discussions/494365
或者我为我的需求解决更快的解决scheme是只创build一个转换types的视图。 这避免了整个问题。
我最近不得不在LINQ查询中将string(数字表示)转换为枚举值,而没有实现查询。 我的枚举使用0到9之间的int值,所以我最终做了这样的事情:
.Select(str => (MyEnum?)(SqlFunctions.Unicode(str) - 48))
我知道这不是提供一个完整的解决scheme,但它确实在像我这样的情况下工作。 也许有些人会觉得有用。
你可以尝试Convert.ToInt32(input);
如果你不确定,你可以TryParse
。 它不会抛出exception,但错误是不能parsing。 但是Convert.ToInt32(input);
应该工作。 你可以在http://msdn.microsoft.com/en-us/library/vstudio/bb397679.aspx上阅读。;