C# 实体框架核心2.2使用标量DBFunction获取外键列表上的属性

C# 实体框架核心2.2使用标量DBFunction获取外键列表上的属性,c#,.net-core,entity-framework-core,user-defined-functions,C#,.net Core,Entity Framework Core,User Defined Functions,我有一个带有外键链接列表的模型,即 [Table("a"] public class A { [Key] [Column("a_id")] public int Id { get; set; } public List<B> Bs { get; set; } = new List<B>(); } [Table("b"] public class B { [Key] [Column("b_id")] public

我有一个带有外键链接列表的模型,即

[Table("a"]
public class A {
    [Key]
    [Column("a_id")]
    public int Id { get; set; }

    public List<B> Bs { get; set; } = new List<B>();
}

[Table("b"]
public class B {
    [Key]
    [Column("b_id")]
    public int Id { get; set; }
    [NotMapped]
    public string MyFunctionValue { get; set; }

    [ForeignKey("a_id")]
    public A A { get; set; }
}
在我的背景下注册,就像这样

public static class MySqlFunctions {
    [DbFunction("MyFunction", "dbo")]
    public static string MyFunction(int bId) {
        throw new NotImplementedException();
    }
}
modelBuilder.HasDbFunction(() => MySqlFunctions.MyFunction(default));
在我的repository类中,我希望能够抓取A记录和列表中链接的B记录,并将它们的MyFunctionValue值设置为针对B id运行时函数的返回值

myContext.A
    .Include(a => a.Bs.Select(b => new B {
        Id = b.Id,
        MyFunctionValue = MySqlFunctions.MyFunction(b.Id)
    });
然而,到目前为止,我尝试过的所有选项中,我要么得到InvalidOperationException,要么得到NotImplementedException,我猜是因为它不能正确地将其转换为SQL

是否有任何方法可以编写这样的查询,或者对于EF来说太复杂而无法生成SQL?我知道我可以使用。FromSql,但如果可能的话,我宁愿避免它,因为它有点凌乱

编辑:

因此,我已经设法让它与以下代码一起工作,但它显然有点混乱,如果有人有更好的解决方案,我将不胜感激

myContext.A
    .Include(a => a.Bs)
    .Select(a => new {
        A = a,
        MyFunctionValues = a.Bs.Select(b => MySqlFunctions.MyFunction(b.Id))
    })
    .AsEnumerable()
    .Select(aWithMfvs => {
        for (int i = 0; i < aWithMfvs.MyFunctionValues.Count(); i++) {
            aWithMfvs.A.Bs[i].MyFunctionValue = aWithMfvs.MyFunctionValues[i];
        }

        return aWithMfvs.A;
    })
    .AsQueryable();
myContext.A
.包括(a=>a.Bs)
.选择(a=>新建{
A=A,
MyFunctionValues=a.Bs.Select(b=>MySqlFunctions.MyFunction(b.Id))
})
.可计算的()
.选择(aWithMfvs=>{
对于(int i=0;i函数有几个事情需要考虑:

  • 当您将DbFunction声明为静态方法时,不必向modelBuilder注册它
  • 只有当您使用Fluent API时才需要注册(无论如何,为了让您的实体不存在任何依赖关系,我建议使用Fluent API)
  • 返回值、方法名称以及方法参数的计数、类型和顺序必须与用户定义函数(UDF)中的代码相匹配
    • 您将方法参数命名为
      bId
      。它在您的UDF中是否完全相同,或者更确切地说,与表中的一样,如
      b_id

感谢您提供这些有用的信息,这些信息我都不知道。然而,我认为我的例子中的问题是,它无法将我的linq查询转换为适当的SQL。因此,它随后尝试调用函数客户端并抛出异常。我已经用我必须编写的代码进行了编辑,以使其正常工作,但显然不够理想。我似乎还需要modelBuilder.hasdb函数。这个线程上的一些响应似乎暗示,如果静态函数在dbcontext之外,就需要它。