【发布时间】:2010-03-15 11:44:09
【问题描述】:
假设我有一个实体对象定义为
public partial class Article
{
public Id
{
get;
set;
}
public Text
{
get;
set;
}
public UserId
{
get;
set;
}
}
根据文章的某些属性,我需要确定文章是否可以被给定用户删除。所以我添加了一个静态方法来进行检查。比如:
public partial class Article
{
public static Expression<Func<Article, bool>> CanBeDeletedBy(int userId)
{
//Add logic to be reused here
return a => a.UserId == userId;
}
}
所以我现在可以做
using(MyEntities e = new MyEntities())
{
//get the current user id
int currentUserId = 0;
e.Articles.Where(Article.CanBeDeletedBy(currentUserid));
}
到目前为止一切顺利。现在我想在执行 Select 时重用 CanBeDeletedBy 中的逻辑,例如:
using(MyEntities e = new MyEntities())
{
//get the current user id
int currentUserId = 0;
e.Articles.Select(a => new
{
Text = a.Text,
CanBeDeleted = ???
};
}
但是无论我怎么尝试,都无法使用select方法中的表达式。我想如果我能做到的话
e.Articles.Select(a => new
{
Text = a.Text,
CanBeDeleted = a => a.UserId == userId
};
那么我应该可以使用相同的表达式。尝试编译表达式并通过执行调用它
e.Articles.Select(a => new
{
Text = a.Text,
CanBeDeleted = Article.CanBeDeletedBy(currentUserId).Compile()(a)
};
但它也不起作用。
关于如何让它发挥作用的任何想法?或者如果不可能,在这两个地方重用业务逻辑的替代方法是什么?
谢谢
佩德罗
【问题讨论】:
-
编译表达式是正确的选择,它编译并为我工作。如果是我,我也会考虑编译。你得到什么错误?
-
是的,它编译得很好,但会引发 NotSupportedException 异常:“LINQ to Entities 不支持 LINQ 表达式节点类型 'Invoke'。”尝试将 Select 之外的表达式编译为 Func
并在内部使用它,结果相同。 -
顺便说一句,如果我使用普通的 Func
,并在 Where 方法中使用它,那么查询将在客户端执行,这不是预期的目的。 -
啊,对不起,我的错 - 错过了你正在使用 EF 的事实 - 它适用于 linq to objects :)