2010-07-29 7 views
9

Tengo un modelo de Entity Framework (v.1.0) que intento extender con una propiedad calculada.Problema de Entity Framework Calculated Problema

He creado la clase parcial para extender la "Oferta" objeto de entidad de esta manera:

namespace MyModelNamespace 
{ 
    public partial class Offer 
    { 
     public bool MyProperty 
     { 
      get 
      { 
       // my stuffs the return true or false 
      } 
     } 
    } 
} 

Se compila sin problema en mi asamblea, pero en tiempo de ejecución, cuando estoy tratando de hacer algo de esta manera:

_myEntities.OfferSet.FirstOrDefault(o=>o.MyProperty); 

puedo recuperar este 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.

... alguna sugerencia ???

Respuesta

5

Sí, puedes hacer esto. Use el LINQ translations library.

+0

interesante ... ¡Lo intentaré lo antes posible! – tanathos

+2

Lo estoy intentando, pero no puedo hacer que funcione :(... He incluido el dll, y compila bien, pero en tiempo de ejecución me sale algo así como: "El miembro especificado 'MyProperty' no es compatible con LINQ to Entities ". He seguido exactamente los ejemplos en el enlace que publicó. – tanathos

+0

@tanathos Su problema probablemente tiene que ver con la inicialización estática. Consulte el comentario de Matyas Boros del 30 de agosto en ese artículo.La solución alternativa propuesta es crear un constructor estático (vacío) en la clase y, a continuación, instanciar una instancia del objeto en algún momento antes de que se consulte. Feo :( – AaronSieb

1

No puede insertar propiedades personalizadas en la base de datos. Deberías haber obtenido algo como

"The specified type member 'MyProperty' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported."

La única manera válida de hacer lo que quieres es ponerlo en la memoria. Y luego filtrar.

_myEntities.OfferSet.ToList().FirstOrDefault(o=>o.MyProperty); 

Supongo que probablemente haya una mejor manera de lograr lo que sea que esté haciendo.

EDITAR Estoy de acuerdo Craig hay otra manera, suponiendo que * se puede traducir en una expresión tienda. Si está mapeando una propiedad para algún tipo de consulta, podrá buscar/presionar hacia abajo el filtro.

+0

No es la única manera; ver mi respuesta –

+0

Tiene razón, estaba asumiendo que estaba tratando de usar algún tipo de propiedad constante o derivada. – Nix

+0

'AsEnumerable()' es mejor que 'ToList()' en este caso. –

0

Una forma de intentarlo es utilizar el espacio de nombres System.Linq.Expressions y el método de extensión AsExpandable disponible here.

Estoy pensando que podría pasar una expresión al método FirstOrDefault, y si aún desea usar MyProperty en otro lugar, podría usar la misma expresión para calcular su valor. Por lo que tendría algo como:

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); 
     } 
    } 
} 

Luego, más tarde, se le pasa en:

_myEntities.OfferSet.AsExpandable().FirstOrDefault(Offer.exp.Compile())); 

Si el cálculo se puede convertir en un árbol de expresión que comprende SQL, creo que esto va a funcionar . Funcionó con una clase de prueba que no es de Entidad, pero usarlo con LINQ to Entities es un animal diferente.

No he usado AsExpandable mucho, por lo que es posible que este código no sea el correcto. Estoy abierto a las correcciones.

+0

'MyFunc' tendría que ser un' Expression

+0

Buen punto. Lo que significa que el lambda debe ser una expresión en su lugar de un bloque de instrucción, así que espero que el cálculo se pueda expresar de esa manera. Editado. –

Cuestiones relacionadas