2012-05-09 12 views
6

Tengo curiosidad sobre cómo crear una propiedad que LINQ pueda traducir. A continuación se muestra un ejemplo muy simple.Crear una propiedad que LINQ to Entities puede traducir

Tengo una tabla/clase Category, que tiene una columna ParentId ligarse a sí mismo (lo tanto, una categoría puede tener sub-categorías)

EF genera automáticamente una propiedad Category1, que es la categoría padre.

En aras de la claridad, he creado otra propiedad

public partial class Category 
{ 
    public Category Parent 
    { 
    get { return Category1; } 
    } 
} 

El problema es que esto funciona

var categs = ctx.Categories.Where(x => x.Category1 == null); 

pero esto no funciona

var categs = ctx.Categories.Where(x => x.Parent == null); 

El el miembro de tipo especificado 'Padre' no es compatible en LINQ to Entities. Solo se admiten inicializadores, miembros de entidades y propiedades de navegación de entidades.

¿Hay alguna manera de crear una propiedad traducible (LINQ to SQL) sin hacer .ToList()?

EDIT: Quiero evitar tocar Model.edmx porque la base de datos a menudo cambia durante el desarrollo y la .edmx menudo tiene que ser recreada

+0

Necesita crear una propiedad de navegación de la categoría a principal como clave foránea –

+0

Hola Cold Told, lo siento, no estoy seguro de lo que quiere decir. Ya hay una clave externa (De lo contrario, EF no creará la Categoría1) – Aximili

+0

¿De verdad ha mirado 'Category1' en Model.Designer.cs y/o Reflector para ver qué atributos u otra parafernalia se agrega a su definición? –

Respuesta

2

Si pregunta si es posible crear una propiedad con cualquier código C# en los getters/setters y luego lo entiende por LINQ estándar a Entities - entonces no, no se puede hacer. C# es mucho más expresivo que SQL y no es razonable esperar que Entity Framework actúe como un traductor general de C# a SQL.

Sin embargo, puedes evitar esto en muchos casos, ver Using a partial class property inside LINQ statement para ver un ejemplo.

actualización

Sería de ayuda si usted nos dijo qué es exactamente lo que quiere lograr, pero aquí hay un ejemplo:

public partial class Category 
{ 
    public static Expression<Func<Category, bool>> ParentIsNullExpression 
    { 
     get 
     { 
      return c => c.Category1 == null; 
     } 
    } 
} 

Y luego

var categs = ctx.Categories.Where(Category.ParentIsNullExpression); 

Todo tipo de las manipulaciones en Expresiones son posibles, algunas de ellas son compatibles con EF y, como tales, se traducen a SQL.

+0

No se puede hacer en C#? Pero Model.Designer.cs en sí (el archivo CS para EDMX) es C#, ¿no? ¿Se refiere a las propiedades que devuelven expresiones de ese enlace? Lo veré. – Aximili

+0

Sí, me refería a las Propiedades de expresión. No es el código de propiedad que lo hace funcionar en Model.Designer.cs, es la expresión que usa para acceder a la propiedad, p. '' c => c.Category''. EF sabe que quiere la propiedad '' Category'' y la traduce a la columna/tabla '' Category''. –

+0

Lo siento, nunca he usado Expression Properties. ¿Estás diciendo que es posible que una propiedad de expresión se traduzca a SQL? ¿Puedes reemplazar la propiedad Parent en mi pregunta con una propiedad de expresión para que LINQ pueda traducirla? Gracias Jacek – Aximili

0

en su diseñador Entity Data Model (archivo .edmx), puede cambiar el nombre del Category1 a Parent

+0

Eso fue solo un ejemplo muy simplificado. Estaba preguntando cómo escribir una propiedad, sin renombrar una existente. Gracias de cualquier manera. – Aximili

0

Usted tiene 4 opciones:

  1. Use el código de primera
  2. añadirlo al diseñador EDMX
  3. Añadir su propiedad a la sección CSDL del EDMX, agregar una columna a la sección SSDL de la EDMX, luego mapea entre sí en la sección de mapeo del EDMX.
  4. Ingrese la consulta en la memoria utilizando .ToList() y luego use LINQ interno en lugar de LINQ para Entidades.
Cuestiones relacionadas