Reputation: 5606
I've an Entity Framework model (v.1.0) that I'm trying to extends with a calculated property.
I've created the partial class to extend the entity object "Offer" in this way:
namespace MyModelNamespace
{
public partial class Offer
{
public bool MyProperty
{
get
{
// my stuffs the return true or false
}
}
}
}
It compiles without problem in my assembly, but at runtime, when I'm trying to do something like this:
_myEntities.OfferSet.FirstOrDefault(o=>o.MyProperty);
I retrieve this error:
The number of members in the conceptual type 'MyModelNamespace.Offer' does not match with the number of members on the object side type 'MyModelNamespace.Offer'. Make sure the number of members are the same.
...any suggestions???
Upvotes: 9
Views: 3430
Reputation: 30700
One way you could try is by using the System.Linq.Expressions namespace and the AsExpandable extension method available here.
I'm thinking you could pass an expression to the FirstOrDefault
method, and if you still want to use MyProperty
elsewhere, you could use the same expression to calculate its value. So you'd have something like:
public partial class Offer
{
public static Expression<Func<Offer, bool>> exp
{
get
{
return o => o.Property1 * o.Property2 == someValue;
}
}
public bool MyProperty
{
get
{
return exp.Compile()(this);
}
}
}
Then later on, you pass it in:
_myEntities.OfferSet.AsExpandable().FirstOrDefault(Offer.exp.Compile()));
If your calculation can be converted into an expression tree that SQL understands, I think this will work. It worked with a non-Entity test class, but using it with LINQ to Entities is a different animal.
I haven't used AsExpandable much, so this code might not be right. I'm open to corrections.
Upvotes: 0
Reputation: 58632
You can't push custom properties down to the database. You should have gotten something like
"The specified type member 'MyProperty' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported."
The only valid way to do what you want is to get it into memory. And then filter.
_myEntities.OfferSet.ToList().FirstOrDefault(o=>o.MyProperty);
I am guessing there is probably a better way to accomplish whatever you are doing.
EDIT I agree Craig there is another way, assuming * it can be translated into a store expression. If you are mapping a property to some type of query, you will be able to search/push down the filter.
Upvotes: 1