f#查询表达式以按列表上的Id获取元素
我使用f#从csv文件更新DB,所以我使用f#查询表达式以按列表上的Id获取元素,f#,F#,我使用f#从csv文件更新DB,所以我使用Fsharp.Data解析它,它按照预期工作正常,然后SqlProvider进行实际更新。 因此,我从csv中获得了一个项目的列表,其中一个字段是我要更新的表的标识符。我来自c#背景,因此使用LINQ我应该做如下操作: var results = context.MyTable.Where(m => myList.Contains(m.Identifier)) 这会让我产生我想要的争吵。我试着这么做 query { for m in ct
Fsharp.Data
解析它,它按照预期工作正常,然后SqlProvider
进行实际更新。因此,我从csv中获得了一个项目的
列表,其中一个字段是我要更新的表的标识符。我来自c#背景,因此使用LINQ
我应该做如下操作:
var results = context.MyTable.Where(m => myList.Contains(m.Identifier))
这会让我产生我想要的争吵。我试着这么做
query {
for m in ctx.Dbo.MyTable do
where (List.contains m.Identifier myList)
select m
}
并在运行时出现此错误:
System.InvalidOperationException:类型为“FSharp.Data.Sql.Common.SqlEntity”的变量“m”从作用域“”引用,但未定义该变量
在Microsoft.FSharp.Linq.RuntimeHelpers.LeafExpressionConverter.EvaluateQuote(FSharpExpr e)上
在Microsoft.FSharp.Linq.QueryModule.EvalNonNestedInner(CanEliminate canElim,FSharpExpr queryProducingSequence)上
在Microsoft.FSharp.Linq.QueryModule上。clo@1727-1.Microsoft FSharp Linq ForwarderyMethods执行[a,b](FSharpExpr`1 q)
地址:$FSI_0006.main@()
由于错误而停止
然后尝试了以下方法
query {
for m in ctx.Dbo.MyTable do
for id in myList do
where (id = m.Identifier)
select m
}
在编译时得到了这个:
myScript.fsx(291,30):错误FS0001:类型“字符串列表”与类型“System.Linq.IQueryable”不兼容
我相信这是可以做到的,我想知道我做错了什么
正确的方法是什么?
我认为这显然是错误的是什么
更新
我只是按照Aaron的回答,这就是我的代码现在的样子,至少相关部分是:
let ctx = Sql.GetDataContext();
let getZipCodes (zipcodes: string list) =
query {
for zc in ctx.CleanZipCodes do
for id in zipcodes do
where (id = zc.ZipCode)
select zc
}
|> Seq.toList
现在我得到了这个错误:
System.Data.EntityCommandExecutionException:执行命令定义时出错。有关详细信息,请参见内部异常。-->
System.Data.SqlClient.SqlException:SQL语句的某些部分嵌套太深。重写查询或将其拆分为较小的查询。
位于System.Data.SqlClient.SqlConnection.OneError(SqlException异常,布尔断开连接,操作'1 wrapCloseInAction)
位于System.Data.SqlClient.TdsParser.ThroweException和Warning(TdsParserStateObject StateObjectObj,布尔调用连接锁,布尔异步关闭)
在System.Data.SqlClient.TdsParser.TryRun(RunBehavior RunBehavior,SqlCommand cmdHandler,SqlDataReader dataStream,BulkCopySimpleResultSet bulkCopyHandler,TdsParserStateObject stateObj,Boolean&dataReady)
位于System.Data.SqlClient.SqlDataReader.TryConsumeMetaData()
在System.Data.SqlClient.SqlDataReader.get_MetaData()
在System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds、RunBehavior RunBehavior、String ResetOptions String、Boolean isInternal、Boolean ForDescriptionParameterEncryption、Boolean shouldCacheForAlwaysEncrypted)
位于System.Data.SqlClient.SqlCommand.RunExecuteReaderDS(CommandBehavior cmdBehavior、RunBehavior RunBehavior、Boolean returnStream、Boolean async、Int32超时、任务和任务、Boolean asyncWrite、Boolean inRetry、SqlDataReader ds、Boolean describeParameterEncryptionRequest)
位于System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior、RunBehavior RunBehavior、Boolean returnStream、String方法、TaskCompletionSource'1 completion、Int32超时、任务和任务、Boolean&usedCache、Boolean asyncWrite、Boolean inRetry)
位于System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior、RunBehavior RunBehavior、Boolean returnStream、String方法)
位于System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior,String方法)
位于System.Data.EntityClient.EntityCommandDefinition.ExecuteStorommands(EntityCommand EntityCommand,CommandBehavior)
---内部异常堆栈跟踪结束--
在System.Data.EntityClient.EntityCommandDefinition.ExecuteStorommands(EntityCommand,EntityCommand,CommandBehavior)中执行命令
在System.Data.Objects.Internal.ObjectQueryExecutionPlan.Execute[TResultType](ObjectContext上下文,ObjectParameterCollection参数值)
位于System.Data.Objects.ObjectQuery'1.GetResults(Nullable'1 forMergeOption)
位于System.Data.Objects.ObjectQuery'1.System.Collections.Generic.IEnumerable.GetEnumerator()
在Microsoft.FSharp.Collections.SeqModule.ToList[T](IEnumerable'1源代码)
地址:$FSI_0006.main@()
第二个示例中的错误似乎是LINQtoSQL的问题。您可以通过使用SQL实体类型提供程序来解决此问题,该提供程序在内置类型提供程序中称为SqlEntityConnection
:
#r "System.Data.Entity"
#r "FSharp.Data.TypeProviders"
open Microsoft.FSharp.Data.TypeProviders
type SqlDb = SqlEntityConnection<"...">
let context = SqlDb.GetDataContext()
let myList = [...]
query {
for record in context.MyTable do
for id in myList do
where (id = record.Identifier)
select record
} |> Seq.toList
#r“系统.数据.实体”
#r“FSharp.Data.TypeProviders”
打开Microsoft.FSharp.Data.TypeProviders
类型SqlDb=SqlEntityConnection
let context=SqlDb.GetDataContext()
让myList=[…]
质疑{
对于context.MyTable do中的记录
对于myList中的id,请执行以下操作:
其中(id=记录.标识符)
选择记录
}|>顺序列表
运行时不知道如何将列表转换为SQL。您需要使用LINQ的扩展方法。Contains
第二个示例适用于SqlEntityConnection
,但不适用于SqlDataConnection
。你用的是哪一种?@FyodorSoikin我明白你的意思,我只是不知道如何使用它,你能给我指点路吗,或者告诉我在工作中可以看到它的地方吗?Thanks@AaronM.Eshbach我正在使用SqlProvider
包和SqlDataProvider
作为上下文提供程序。我应该如何使用你正在使用的那个?感谢阅读最新编辑,您当地的邮政编码列表有多大?它适用于一个或两个邮政编码的列表吗?很抱歉,我刚刚尝试了此操作,但出现了此错误错误FS0001:类型“string list”与类型“System.Linq.IQueryable”不兼容。