views:

152

answers:

3

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???

A: 

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.

Nix
Not the only way; see my answer.
Craig Stuntz
You are correct, i was assuming he was trying to use some type of constant or derived property.
Nix
`AsEnumerable()` is better than `ToList()` in this case.
Matt Greer
+1  A: 

Yes, you can do this. Use the LINQ translations library.

Craig Stuntz
interesting... I'll try as soon as possible!
tanathos
I'm trying it, but I can't get it to work :( ... I've included the dll, and it compiles well, but at runtime I get something like: "Specified member 'MyProperty' not supported by LINQ to Entities.". I've exactly followed the examples in the link you posted.
tanathos
A: 

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.

Justin Morgan
`MyFunc` would need to be an `Expression<Func<…` (all the way back to its declaration), not a `Func<…`
Craig Stuntz
Good point. Which means the lambda needs to be an expression instead of a statement block, so I hope the calculation can be expressed that way. Edited.
Justin Morgan