C# 将LINQ子查询移动到扩展方法在运行时失败
我正在LINQPad中计算这个LINQ查询。我在做这样的事情:C# 将LINQ子查询移动到扩展方法在运行时失败,c#,linq,C#,Linq,我正在LINQPad中计算这个LINQ查询。我在做这样的事情: var perms = (from x in db.TableName // etc select new ProfilePermission { // etc }); perms = perms.Concat(from x in db.TableName // etc select new ProfilePermission
var perms = (from x in db.TableName // etc
select new ProfilePermission
{ // etc
});
perms = perms.Concat(from x in db.TableName // etc
select new ProfilePermission
{ // etc
});
var results = (from pi in db.AnotherTable
where pi.IsActive
select new MyViewModel
{
KeyId = pi.Id,
Permissions = (from pm in perms
where pi.ChildId == pm.ChildId
select pm)
}
使用此子查询可以工作。所以,我想,让我们把它转移到一个扩展方法。我试着这样做:
public static IQueryable<ProfilePermission> GetProfilePermissions
(
this IMkpContext db
)
{
var perms = (from x in db.TableName // etc
select new ProfilePermission
{ // etc
});
perms = perms.Concat(from x in db.TableName // etc
select new ProfilePermission
{ // etc
});
return perms;
}
var results = (from pi in db.AnotherTable
where pi.IsActive
select new MyViewModel
{
KeyId = pi.Id,
Permissions = (from pm in db.GetProfilePermissions()
where pi.ChildId == pm.ChildId
select pm)
}
公共静态IQueryable GetProfilePermissions
(
这是IMKP上下文数据库
)
{
var perms=(从db.TableName//等中的x开始)
选择“新建配置文件”权限
{//等
});
perms=perms.Concat(从db.TableName//等中的x开始)
选择“新建配置文件”权限
{//等
});
回烫;
}
var结果=(来自db.AnotherTable中的pi
其中pi.i是活动的
选择新的MyViewModel
{
KeyId=pi.Id,
权限=(从db.GetProfilePermissions()中的pm)
其中pi.ChildId==pm.ChildId
选择pm)
}
现在我得到一个信息:
NotSupportedException:LINQ to Entities无法识别方法'System.LINQ.IQueryable'1[PublicationSystem.Model.ViewModels.ProfilePermission]GetProfilePermissions(PublicationSystem.Model.IMkpContext)'方法,此方法无法转换为存储表达式
为什么子查询以一种方式工作,而不是以另一种方式工作?我认为perms最终都是一个
IQueryable
。不同之处在于,在您使用扩展方法的地方,它没有被执行,而是成为另一个表达式的一部分(Select
),即被存储为EF查询提供程序无法识别的方法的MethodCallExpression
如果您确实在一些顶级查询构造(如Join
或GroupJoin
)中使用扩展方法,它将起作用。或者如果您可以将调用移到查询之外,并将结果存储到变量中
例如,在您的情况下,以下操作将起作用:
var results =
from pi in db.AnotherTable
where pi.IsActive
join pm in db.GetProfilePermissions() on pi.ChildId equals pm.ChildId into permissions
select new MyViewModel
{
KeyId = pi.Id,
Permissions = permissions
};
除此之外:
var permissions = db.GetProfilePermissions();
var results =
from pi in db.AnotherTable
where pi.IsActive
select new MyViewModel
{
KeyId = pi.Id,
Permissions = (from pm in permissions
where pi.ChildId == pm.ChildId
select pm)
};
我通常只使用以下方法来解释问题和解决方案:publicstaticobjectgetprofilepermissions