使用 SQL Server 数据库将 SQL 查询转换为 Linq
Posted
技术标签:
【中文标题】使用 SQL Server 数据库将 SQL 查询转换为 Linq【英文标题】:Converting a SQL query to Linq using a SQL Server database 【发布时间】:2021-09-14 21:29:48 【问题描述】:select *
from Enrollment
where Atnper <= 70
我在 linq 中尝试了这个,但我得到一个错误:
var atn = db.Enrollments
.Where(a => a.cid == cid &&
a.Section == sect &&
int.Parse(a.Atnper)<= 75)
.Select(m => m.Atnper);
这是我得到的错误:
System.InvalidOperationException:“ObjectContent`1”类型无法序列化内容类型“application/json”的响应正文; charset=utf-8'。
SystemNotSupportedException:LINQ to Entities 无法识别方法“Int32 Parse(System.String)”方法,并且该方法无法转换为存储表达式。
堆栈跟踪 在 System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.DefaultTranslator.Translate(ExpressionConverter parent, MethodCallExpression call) 在 System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate(ExpressionConverter 父级,MethodCallExpression linq) 在 System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression(表达式 linq)\r\n 在 System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.BinaryTranslator.TypedTranslate(ExpressionConverter 父级,BinaryExpression linq)\r\n at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression(表达式 linq)\r\n 在 System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.BinaryTranslator.TypedTranslate(ExpressionConverter 父级,BinaryExpression linq)\r\n at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression(表达式 linq)\r\n 在 System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateLambda(LambdaExpression lambda,DbExpression 输入)\r\n at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.OneLambdaTranslator.Translate(ExpressionConverter 父级、MethodCallExpression 调用、DbExpression& 源、 DbExpressionBinding& sourceBinding, DbExpression& lambda)\r\n at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.OneLambdaTranslator.Translate(ExpressionConverter 父,MethodCallExpression 调用)\r\n at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate(ExpressionConverter 父,MethodCallExpression linq)\r\n at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression(表达式 linq)\r\n 在 System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.OneLambdaTranslator.Translate(ExpressionConverter 父级、MethodCallExpression 调用、DbExpression& 源、 DbExpressionBinding& sourceBinding, DbExpression& lambda)\r\n at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.SelectTranslator.Translate(ExpressionConverter 父,MethodCallExpression 调用)\r\n at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate(ExpressionConverter 父,MethodCallExpression linq)\r\n at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression(表达式 linq)\r\n 在 System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.Convert()\r\n 在 System.Data.Entity.Core.Objects.ELinq.ELinqQueryState.GetExecutionPlan(Nullable
1 forMergeOption)\r\n at System.Data.Entity.Core.Objects.ObjectQuery
1.c__DisplayClass7.b__6()\r\n 在 System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)\r\n at System.Data.Entity.Core.Objects.ObjectQuery
1.c__DisplayClass7.b__5()\r\n 在 System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func1 operation)\r\n at System.Data.Entity.Core.Objects.ObjectQuery
1.GetResults(Nullable1 forMergeOption)\r\n at System.Data.Entity.Core.Objects.ObjectQuery
1.b__0()\r\n 在 System.Data.Entity.Internal.LazyEnumerator`1.MoveNext()\r\n 在 Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeList(JsonWriter writer,IEnumerable 值,JsonArrayContract 合同,JsonProperty 成员,JsonContainerContract 集合合同,JsonProperty containerProperty)\r\n 在 Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize(JsonWriter jsonWriter,对象值,类型 objectType)\r\n at Newtonsoft.Json.JsonSerializer.SerializeInternal(JsonWriter jsonWriter,对象值,类型 objectType)\r\n at System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.WriteToStream(类型 类型、对象值、流 writeStream、编码 有效编码)\r\n 在 System.Net.Http.Formatting.JsonMediaTypeFormatter.WriteToStream(类型 类型、对象值、流 writeStream、编码 有效编码)\r\n 在 System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.WriteToStreamAsync(类型 类型、对象值、流 writeStream、HttpContent 内容、 TransportContext transportContext, CancellationToken cancelToken)\r\n--- 来自先前位置的堆栈跟踪结束 抛出异常的地方 ---\r\n 在 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务 任务)\r\n 在 System.Web.Http.WebHost.HttpControllerHandler.d__22.MoveNext()"
【问题讨论】:
你检查过你的错误 AtnPer 是数据库中的数字字符串吗?它总是数字吗?将其转换为 int 列类型并修复您的实体以使用 int 属性并删除 int.Parse 你用的是什么版本的EF? 需要有关类模型、映射、EF 版本、数据类型的详细信息。此外,还有很多关于“LINQ to Entities 无法识别方法......”的问题。您是否尝试过自己寻找答案? 【参考方案1】:从错误看来,您使用的是 EF6 或更早版本。我认为 EF 没有内置方法来调用字符串到数字的转换,但是您可以创建一个用户定义的函数来执行它并调用它 - 请参阅 https://docs.microsoft.com/en-us/previous-versions/dotnet/netframework-4.0/dd456847(v=vs.100) (但要解决可能的问题需要做很多工作数据建模中的缺陷))
--
您可以升级到 EF 核心并将您的 int.Parse 更改为 Convert.ToInt32(a.AtnPer)
,以便 EFC 将在 db 端使用 CONVERT(int, AtnPer)
,但是要解决数据建模中可能存在的缺陷需要做很多工作
如果您的列始终将 int 存储在字符串中,请将其更改为 int 类型列并将您的 C# 实体更改为 int
如果你在你的实体中犯了一个错误,db列是一个int,而实体是一个字符串,然后将实体修复为int并删除int解析
这里是您可以在 EFC LINQ 中使用的函数列表,因为它知道如何将它们转换为 sql server 中的某些内容:https://docs.microsoft.com/en-us/ef/core/providers/sql-server/functions
对于旧版 EF https://docs.microsoft.com/en-us/previous-versions/dotnet/netframework-4.0/dd456828(v=vs.100)?redirectedfrom=MSDN 的类似建议
【讨论】:
【参考方案2】:这样的另一种方式:
var atn = db.Enrollments
.Where(a => a.cid == cid &&
a.Section == sect &&
a.Atnper.Lenght <= 2 &&
a.Atnper <= "75")
.Select(m => m.Atnper);
【讨论】:
请记住,字符串排序不同于整数排序。"100" < "75"
为真,100 < 75
为假。这正是他们尝试解析字符串的原因。
当然,这就是我添加a.Atnper.Lenght <= 2
的原因,但看起来这不正确。试试这个:(a.Atnper.Lenght < 2 || (a.Atnper.Lenght == 2 && a.Atnper <= "75"))
是的,但这是一个不切实际的限制。以上是关于使用 SQL Server 数据库将 SQL 查询转换为 Linq的主要内容,如果未能解决你的问题,请参考以下文章
使用 LIKE 将 Oracle 查询转换为 SQL Server 查询
SQL Server 2008 R2 - 将查询结果保存为 phpmyadmin 可读的 SQL 语句?
如何将查询从 phpMyAdmin SQL Dump 转换为 sql server 易读查询
将查询从 SQL Server 转换为 Access 2000