C# 为什么接收到指定的LINQ表达式包含对与不同上下文关联的查询的引用?
例外情况:C# 为什么接收到指定的LINQ表达式包含对与不同上下文关联的查询的引用?,c#,entity-framework,linq,C#,Entity Framework,Linq,例外情况: System.NotSupportedException:'指定的LINQ表达式包含对与不同上下文关联的查询的引用。' 代码: IEnumerable<EntityIdName> entitiesIDs = (from a in afimDB.UNITES select new EntityIdName { entityId = (int)a.UNIT_ID, entityName = a.UNIT_NAME }) .AsEnumerable(
System.NotSupportedException:'指定的LINQ表达式包含对与不同上下文关联的查询的引用。' 代码:
IEnumerable<EntityIdName> entitiesIDs =
(from a in afimDB.UNITES
select new EntityIdName { entityId = (int)a.UNIT_ID, entityName = a.UNIT_NAME })
.AsEnumerable();
var usersWithEntities = (
from user in imdb.AspNetUsers
select new
{
UserId = user.Id,
Username = user.UserName,
Email = user.Email,
EntityNames = (
from a in imdb.UserEntities
join b in imdb.AspNetUsers on a.UserID equals b.Id
where user.Id == a.UserID
select new
{
entity = (
from q in entitiesIDs
where q.entityId == 2
select q.entityName)
.ToArray()
})
.ToList()
})
.AsEnumerable()
.Select(p => new Users_in_Entities_ViewModel()
{
UserId = p.UserId,
Username = p.Username,
Email = p.Email,
Entity = string.Join(",", p.EntityNames)
});
IEnumerable EntitiesId=
(来自afimDB.UNITES中的a)
选择新的EntityIdName{entityId=(int)a.UNIT\u ID,entityName=a.UNIT\u NAME})
.AsEnumerable();
var userswithenties=(
来自imdb.AspNetUsers中的用户
选择新的
{
UserId=user.Id,
Username=user.Username,
Email=user.Email,
EntityName=(
从imdb.UserEntities中的
在a.UserID等于b.Id的情况下将b加入imdb.AspNetUsers
其中user.Id==a.UserID
选择新的
{
实体=(
从EntitiesID中的q开始
其中q.entityId==2
选择q.entityName)
.ToArray()
})
托利斯先生()
})
.可计算的()
.Select(p=>实体视图模型()中的新用户)
{
UserId=p.UserId,
用户名=p.用户名,
电子邮件,
Entity=string.Join(“,”p.EntityName)
});
这部分查询毫无意义:
EntityNames = (
from a in imdb.UserEntities
join b in imdb.AspNetUsers on a.UserID equals b.Id
where user.Id == a.UserID
select new
{
entity = (
from q in entitiesIDs
where q.entityId == 2
select q.entityName)
.ToArray()
})
.ToList()
})
为什么要从一个表中选择数据,然后连接到另一个表以完全放弃它
这可以简化很多:
string unitNames = string.Join(", ", afimDB.UNITES
.Where(a => a.UNIT_ID == 2)
.Select(a => a.UNIT_NAME));
var usersWithEntities = (
from user in imdb.AspNetUsers
select new Users_in_Entities_ViewModel
{
UserId = user.Id,
Username = user.UserName,
Email = user.Email,
Entity = unitNames
});
您收到的错误是由于:
IEnumerable<EntityIdName> entitiesIDs =
(from a in afimDB.UNITES
select new EntityIdName { entityId = (int)a.UNIT_ID, entityName = a.UNIT_NAME })
.AsEnumerable();
现在您将拥有EntityIdName的POCO列表,可以在第二个EF表达式中引用该列表。EF将对imDB上下文执行第二个查询,该imDB上下文无法加入afimDB上下文中的表达式
编辑:演示行为和调整。这只是一个使用2个DbContext实例作用域的示例,以演示一个上下文中的查询不能在另一个上下文中使用
using (var context2 = new TestDbContext())
{
var ids = context2.Customers
.Where(x => x.Name == "Fred")
.Select(x => x.CustomerId)
.AsEnumerable();
using (var context = new TestDbContext())
{
var customers = context.Customers.Where(x => ids.Contains(x.CustomerId))
.ToList();
}
}
上述操作失败,检索“指定的LINQ表达式包含对与不同上下文关联的查询的引用”的客户时出现异常
使用(var context2=newtestdbcontext())
{
var id=context2.Customers
.其中(x=>x.Name==“Fred”)
.选择(x=>x.CustomerId)
.ToList();//id.Contains(x.CustomerId))
.ToList();
}
}
一切正常.ToList()
对数据库执行第一次查询,并将其放入POCO列表中,该列表在第二次查询的范围内是安全的.AsEnumerable()
不会
请保留有建设性的评论,或许在否决投票前尝试一下。这是您的实际代码吗?因为它看起来甚至不应该编译。你到底想得到什么样的结果?我想知道你从哪里得到这样的信息:“AsEnumerable不执行EF表达式。”因为这是不正确的。请阅读以了解其错误原因“使用AsEnumerable vs.ToList的优点是AsEnumerable不执行查询。AsEnumerable保留延迟执行,并且不构建通常无用的中间列表。”在这种情况下,延迟执行会导致跨DbContext查询。哦,天哪。。。请阅读您链接到的完整答案,其中链接到另一个答案:“当您希望强制查询的一部分以SQL(或类似形式)运行,而其余部分以LINQ to对象运行时,通常会使用它。”AsEnumerable不执行LINQ to Objects查询,但它不执行LINQ to Entities查询,除非它不执行。。试试看<代码>使用(var-context=new-TestDbContext()){var-customers=context.customers.Where(x=>x.Name==“Steve”).AsEnumerable();//SQL没有激发..var-test=customers.ToList();//但在这之后激发…}我有一个跟踪,每行都有一个断点。
.AsEnumerable()
的执行未执行查询。。.ToList()
没有。如果它不涉及数据库,则需要第一个DbContext,实体不能在第二个范围内联接。这里的“context2”和“context”都指同一个“TestDbContext”,而我的“afimDB”和“imDB”则不指代。但是这部分代码不符合我的尝试:string unitNames=string.join(“,”,afimDB.UNITES.Where(a=>a.UNIT\u ID==2)。选择(a=>a.UNIT\u NAME));其中user.ID==a。UserID@Sameer什么?你的代码没有这样做。我建议你重新阅读你发布的内容
using (var context2 = new TestDbContext())
{
var ids = context2.Customers
.Where(x => x.Name == "Fred")
.Select(x => x.CustomerId)
.AsEnumerable();
using (var context = new TestDbContext())
{
var customers = context.Customers.Where(x => ids.Contains(x.CustomerId))
.ToList();
}
}
using (var context2 = new TestDbContext())
{
var ids = context2.Customers
.Where(x => x.Name == "Fred")
.Select(x => x.CustomerId)
.ToList(); // <- The .ToList you need
using (var context = new TestDbContext())
{
var customers = context.Customers.Where(x => ids.Contains(x.CustomerId))
.ToList();
}
}