gpt4 book ai didi

c# - select 子句表达式问题

转载 作者:行者123 更新时间:2023-11-30 17:45:57 26 4
gpt4 key购买 nike

我正在试验 F#,因此决定使用 F# 作为新项目的服务层。现在我正在尝试将实体映射到 F# 类型,但一无所获!问题似乎出在 Select 子句上。

在下面的示例中,IDataContext 是一个 Entity Framework 工作单元,带有一个 DbSet(在 C# 项目中定义)

interface IDataContext
{
DbSet<Person> Persons { get; }
}

方法一

[<CLIMutable>]
type Person = {
Id: int
Name: string
}

type PersonService(context: IDataContext)
member this.GetPerson(personId) =
let person = context.Persons
.Where(fun p -> p.Id = personId)
.Select(fun p -> { Id = p.Id; Name = p.Name })
.FirstOrDefaultAsync()
person

这里似乎出现的问题是 linq 提示需要无参数构造函数。所以我尝试了另一种方式

type public Person() =
[<DefaultValue>] val mutable Id : int
[<DefaultValue>] val mutable Name : string

type PersonService(context: IDataContext)
member this.GetPerson(personId) =
let person = context.Persons
.Where(fun p -> p.Id = personId)
.Select(fun p -> new Person(Id = p.Id, Name = p.Name))
.FirstOrDefaultAsync()
person

现在我明白了

could not convert the following f# quotation to a linq expression tree

我是否必须将 fun 转换为表达式?我以为 F# 3.0 已经做到了?

编辑

在上一个示例中,我只是尝试了 Select(fun p -> new Person()) 并且它有效。那么它初始化属性的方式不好吗? fun p -> new Person(Id = p.Id, Name = p.Name) 对应的 C# 是什么?

最佳答案

如果您想使用 LINQ 和异步查询,您需要变通,因为 LINQ select 不支持记录,您需要使用 async workflow :

type PersonService(context: IDataContext)
member this.GetPerson(personId) =
async {
// get the actual context object
let! person = Async.AwaitTask
(context.Persons
.Where(fun p -> p.Id = personId)
.FirstOrDefaultAsync()))

// map context object, if it's not null
if obj.ReferenceEquals(person, null)
then return None
else return Some ({ Id = person .Id; Name = person .Name })
} |> Async.StartAsTask

值得注意的是,LINQ 和查询表达式可以返回空值,您必须在某些时候处理空值。我更喜欢尽快将它们翻译成选项。此外,我使用 Async.StartAsTask 将 Async 对象转换为热任务。

编辑:

为了限制返回实体的大小,我认为这会起作用(我现在没有时间对此进行全面测试):

type PersonService(context: IDataContext) =
member this.GetPerson(personId) =
async {
// get the actual context object
let! person = Async.AwaitTask
(query { for p in context.Persons do
where (p.Id = personId)
select (p.Id, p.Name)
}).FirstOrDefaultAsync()

// map context object, if it's not null
if obj.ReferenceEquals(person, null)
then return None
else return person |> (fun (id, name) -> Some ({ Id = id; Name = name }))
} |> Async.StartAsTask

关于c# - select 子句表达式问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26961004/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com