首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >linq和可能的实体框架中的F#类型推断问题

linq和可能的实体框架中的F#类型推断问题
EN

Stack Overflow用户
提问于 2011-11-22 23:12:23
回答 2查看 239关注 0票数 2

我只想做这样简单的事情:

代码语言:javascript
运行
复制
context.Users.Any(fun currentUser -> currentUser.UserName = userName)

其中上下文只是一个实体框架上下文。现在,当我在"currentUser“上盘旋时,它知道它是一个用户类型。不过,我得到的是:

根据此程序点之前的信息查找不确定类型的对象。在此程序点之前可能需要一个类型注释来约束对象的类型。这可能会使查找问题得到解决。

现在我意识到我可以这样做:

代码语言:javascript
运行
复制
context.Users.Any(fun (currentUser:User) -> currentUser.UserName = userName)

但是,这似乎很愚蠢,因为c#可以很容易地推断出以下类型:

代码语言:javascript
运行
复制
context.Users.Any(currentUser => currentUser.UserName = userName)

完整的方法是:

代码语言:javascript
运行
复制
let FindAndRemoveUser(userName:String, context:StoryBoardContext) =
  if context.Users.Any(fun currentUser-> currentUser.UserName = userName) then
    let foundUser = context.Users.Where(fun innerUser -> innerUser.UserName = userName).First()
    context.Users.DeleteObject(foundUser)
    context.SaveAll() |> ignore

我是否错误地认为F#应该处理类型推断,或者比C#更好?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-11-23 00:29:55

我认为你的方法有一个更根本的问题,而不仅仅是你描述的问题。将WhereAny与C#中的lambda表达式一起使用时,C#编译器将lambda转换为表达式树Expression<Func<_, _>>,因此LINQ实体可以将代码转换为C#查询。

但是,当您使用F# lambda函数作为参数时,它将被编译为一个函数(或者Func<_, _>类型的委托)。这意味着您的代码将调用内存中的处理函数版本,您将在内存中完成所有处理,而不是在数据库服务器上执行!

要在F# 2.0中编写查询,您需要将所有代码包装在一个引号中,并使用来自F# PowerPackquery函数运行它(F# 3.0将使它变得更好,但不幸的是,这只是一个测试版)。你可能需要这样的东西:

代码语言:javascript
运行
复制
if query <@ context.Users |> Seq.exists (fun currentUser -> 
              currentUser.UserName = userName) @> then
     let foundUser = 
       query <@ context.Users 
                |> Seq.filter (fun usr -> usr.UserName = userName) 
                |> Seq.head @>
     context.Users.DeleteObject(foundUser)  
     context.SaveAll() |> ignore  

(另外,我不确定您是否需要预先检查用户是否存在-您只需要找到所有使用filter的用户,然后如果返回的序列包含什么内容,则删除第一个用户)

票数 4
EN

Stack Overflow用户

发布于 2011-11-22 23:24:26

我认为context.Users是一个seq<User>,所以您可以在Seq模块上使用高阶函数。与Linq相比,您将受益于F#序列中的类型推断:

代码语言:javascript
运行
复制
let FindAndRemoveUser(userName:String, context:StoryBoardContext) =
  if context.Users |> Seq.exists (fun currentUser -> currentUser.UserName = userName) then
    let foundUser = context.Users |> Seq.filter (fun innerUser -> innerUser.UserName = userName) |> Seq.head
    context.Users.DeleteObject(foundUser)
    context.SaveAll() |> ignore

在Linq和F#序列这里中有一个关于类型推断的有趣线程。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8235234

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档