Suppose I have an entity object defined as
public partial class Article
{
public Id
{
get;
set;
}
public Text
{
get;
set;
}
public UserId
{
get;
set;
}
}
Based on some properties of an Article, I need to determine if the article can be deleted by a given user. So I add a static method to do the checking. Something like:
public partial class Article
{
public static Expression<Func<Article, bool>> CanBeDeletedBy(int userId)
{
//Add logic to be reused here
return a => a.UserId == userId;
}
}
So now I can do
using(MyEntities e = new MyEntities())
{
//get the current user id
int currentUserId = 0;
e.Articles.Where(Article.CanBeDeletedBy(currentUserid));
}
So far so good. Now I want to reuse the logic in CanBeDeletedBy while doing a Select, something like:
using(MyEntities e = new MyEntities())
{
//get the current user id
int currentUserId = 0;
e.Articles.Select(a => new
{
Text = a.Text,
CanBeDeleted = ???
};
}
But no matter what I try, I can't use the expression in the select method. I guess that If I can do
e.Articles.Select(a => new
{
Text = a.Text,
CanBeDeleted = a => a.UserId == userId
};
Then I should be able to use the same expression. Tried to compile the expression and call it by doing
e.Articles.Select(a => new
{
Text = a.Text,
CanBeDeleted = Article.CanBeDeletedBy(currentUserId).Compile()(a)
};
but it won't work either.
Any ideas on how to get this to work? Or if it isn't possible, what are the alternatives to reuse business logic in both places?
Thanks
Pedro
Re-using expression trees is a black art; you can do it, but you would need to switch a lot of code to reflection and you'd lose all the static checking. In particular, working with the anonymous types becomes a nightmare (although dynamic
in 4.0 might be workable).
Further, if you cheat and use Expression.Invoke
, then it isn't supported by all providers (most noticeably not on EF in .NET 3.5SP1).
Unless this is a major pain point, I'd leave it with duplication. Or do you need to re-use the expression tree?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With