a.Name == -6ren">
gpt4 book ai didi

.net - Entity Framework : Can't use "Contains" with property on another object

转载 作者:行者123 更新时间:2023-12-02 02:16:57 32 4
gpt4 key购买 nike

抱歉标题不好...这个最好用一个例子来解释:

void Main()
{
IQueryable<ClassA> toLinkTo = context.ClassAs.Where(a => a.Name == "SomeName");

var queryToExecute = context.ClassBs.Where(cb => toLinkTo.Select(ca => ca.Id).Contains(cb.Id));

// This works.
leafNodesWithExternalChildren.ToList();

// This doesn't work.
toLinkTo = new OtherClass(context).LinkedClassAs;
leafNodesWithExternalChildren.ToList();
}

public class OtherClass
{
private MyContext m_Context;

public OtherClass(MyContext ctx)
{
this.m_Context = ctx;
}

public IQueryable<ClassA> LinkedClassAs
{
get
{
// Same as toLinkTo as it was originally declared above.
return this.m_Context.ClassAs.Where(a => a.Name == "SomeName");
}
}
}

toLinkTo 是在本地声明的,但使用完全相同的 IQueryable 作为另一个对象的属性时,这是怎么回事?我得到的异常(exception)是:

无法创建“ClassA”类型的常量值。仅支持原始类型(“例如 Int32、String 和 Guid”)。

提前致谢。

最佳答案

你的第二个例子也有效 - 如果你把它作为第一个例子:

IQueryable<ClassA> toLinkTo = new OtherClass(context).LinkedClassAs;
var queryToExecute = context.ClassBs.Where(cb => toLinkTo.Select(ca => ca.Id)
.Contains(cb.Id));

// Now, this works.
queryToExecute.ToList();

// Now, this doesn't work.
toLinkTo = context.ClassAs.Where(a => a.Name == "SomeName");
queryToExecute.ToList();

Somwhow,在第二次尝试中,EF 预先单独执行 toLinkTo 查询(就好像它会将 AsEnumerable() 附加到查询中一样)以创建一个集合首先是内存中的对象。 queryToExecute 不适用于此集合 - 如@mellamokb 的回答中所述。在第一次尝试中,查询作为一个整体执行,没有出现问题。

如果您为第二个示例创建一个新的 queryToExecute2 变量,则这两个示例都有效:

IQueryable<ClassA> toLinkTo = context.ClassAs.Where(a => a.Name == "SomeName");
var queryToExecute = context.ClassBs.Where(cb => toLinkTo.Select(ca => ca.Id)
.Contains(cb.Id));

// this works.
queryToExecute.ToList();

// And this works too.
toLinkTo = new OtherClass(context).LinkedClassAs;
var queryToExecute2 = context.ClassBs.Where(cb => toLinkTo.Select(ca => ca.Id)
.Contains(cb.Id));
queryToExecute2.ToList();

这可能与 queryToExecute 的表达式树的构建方式以及它如何使用局部变量 toLinkTo 或 EF 如何评估树有关,但它是超出我的视野,无法真正理解或解释到底发生了什么。

编辑

即使您对 toLinkTo 使用完全相同的查询,第二次尝试也不起作用:

IQueryable<ClassA> toLinkTo = context.ClassAs.Where(a => a.Name == "SomeName");
var queryToExecute = context.ClassBs.Where(cb => toLinkTo.Select(ca => ca.Id)
.Contains(cb.Id));

// this works.
queryToExecute.ToList();

// this doesn't work.
toLinkTo = context.ClassAs.Where(a => a.Name == "SomeName");
queryToExecute.ToList();

关于.net - Entity Framework : Can't use "Contains" with property on another object,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10013949/

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