6

Tengo una situación en la que me gustaría utilizar una única clase de lógica de negocios para realizar operaciones similares en una variedad de clases de marcos de entidad. He definido una interfaz que estas clases implementan en un archivo de clase parcial.LINQ a entidades a través de la propiedad de interfaz

Sin embargo, cuando intento escribir una consulta LINQ para las entidades en relación con estos métodos de interfaz, recibo una NotSupportedException ya que la consulta no utiliza las propiedades de la clase directamente, sino a través de una interfaz.

Me gustaría mantener el trabajo pesado en el nivel de la base de datos así que ¿hay alguna manera de lograr esto sin recurrir a LINQ a los objetos?

Aquí hay un código que demuestra mi problema (está utilizando una clase de repositorio genérico creado por una fábrica).

public interface INamedEntity 
{ 
    int ID { get; set; } 
    string Name { get; set; } 
} 

// This is an Entity Framework class which has CustomerID and CustomerName properties. 
public partial class Customer: INamedEntity 
{ 
    int INamedEntity.ID 
    { 
     get { return this.CustomerID; } 
     set { this.CustomerID = value; } 
    } 
    string INamedEntity.Name 
    { 
     get { return this.CustomerName; } 
     set { this.CustomerName = value; } 
    } 
} 

... 

public string GetName<T>(int entityID) where T: EntityObject, INamedEntity 
{ 
    using(var repository = RepositoryFactory.CreateRepository<T>()) 
    { 
     return repository 
      .Where(e => e.ID == entityID) 
      .Select(e.Name) 
      .Single(); 
    } 
} 

Respuesta

0

La siguiente excepción se produce durante la ejecución de consultas basada en una fuente genérica y con un miembro de interfaz utilizado en la cláusula where.

NotSupportedException: no se admite la asignación del miembro de la interfaz [Nombre de la interfaz]. [Nombre del miembro].

La excepción se produce solo cuando la consulta debe devolver varios elementos y cuando utilicé == operator. No pude reproducir el error cuando ejecuté la consulta con First, FirstOrDefault o Single, o cuando utilicé equals u otro operador en la cláusula where.

Referencia: Interface not supported

+0

Sí, se parece al problema. – gareththegeek

5

Esto no es compatible. Su consulta de Linq a entidades solo puede usar propiedades mapeadas de sus entidades. Si usa propiedades de interfaz, EF no sabe cómo convertirlas a SQL porque no puede analizar su código en la implementación de propiedades.

No utilice interfaces para entidades - EF no lo admite en absoluto. En su caso especial, incluso no funcionará con ningún otro ORM porque está consultando propiedades que son desconocidas para el mapeo. Esto requeriría que construyes tu propio proveedor de Linq traduciendo tu consulta para consultar con propiedades mapeadas reales.

+0

Pero, ¿hay alguna forma de lograr este tipo de patrón? Idealmente, habría unidades de lógica de negocios para cada área de funcionalidad, trabajando en una interfaz y mapeando a todas las entidades relevantes. – gareththegeek

+1

Pero eso significa otra capa de "mapeo" encima de EF que traducirá sus propiedades de interfaz de lógica de negocios a propiedades de EF reales. Esta capa de mapeo también transformará las consultas. No llamo a este patrón; lo llamo aplicación arquitectónica. –

+0

Sobre-estructurado tal vez, pero ¿cómo evitar copiar y pegar el mismo código en varios objetos de capa de negocio para que puedan realizar la misma lógica, pero utilizando propiedades de entidad con nombre diferente? – gareththegeek

Cuestiones relacionadas