6

Ho una situazione in cui vorrei utilizzare una singola classe di business logic per eseguire operazioni simili su una varietà di classi di entità framework. Ho definito un'interfaccia che queste classi implementano in un file di classe parziale.LINQ alle entità tramite la proprietà di interfaccia

Tuttavia, quando provo a scrivere un LINQ su query di entità con questi metodi di interfaccia, ottengo un NotSupportedException poiché la query non utilizza direttamente le proprietà della classe ma tramite un'interfaccia.

Mi piacerebbe mantenere il sollevamento pesante del livello di database, quindi c'è un modo per raggiungere questo obiettivo senza ricorrere a LINQ per gli oggetti?

Ecco un codice che dimostra il mio problema (si sta utilizzando una classe di repository generica creata da una factory).

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

risposta

0

La seguente eccezione si verifica durante l'esecuzione della query basata su una sorgente generica e con membro dell'interfaccia utilizzato nella clausola where.

NotSupportedException: la mappatura del membro dell'interfaccia [InterfaceName]. [MemberName] non è supportata.

L'eccezione si verifica solo quando la query deve restituire più elementi e quando ho usato l'operatore ==. Non è stato possibile riprodurre l'errore quando si eseguiva la query con First, FirstOrDefault o Single, o quando si utilizzava un operatore uguale o un altro nella clausola where.

Riferimento: Interface not supported

+0

Sì, sembra il problema. – gareththegeek

5

Questo non è supportata. La tua query Linq-to-entities può utilizzare solo proprietà mappate delle tue entità. Se si utilizzano le proprietà dell'interfaccia, EF non sa come convertirle in SQL perché non è in grado di analizzare il codice nell'implementazione della proprietà.

Non utilizzare le interfacce per le entità - EF non lo supporta affatto. Nel tuo caso speciale, non funzionerà nemmeno con altri ORM perché stai interrogando su proprietà che sono sconosciute alla mappatura. Ciò richiederebbe di costruire il proprio provider Linq per tradurre la query in query con proprietà mappate reali.

+0

Ma c'è un modo per ottenere questo tipo di schema. Idealmente ci sarebbero unità di business logic per ogni area di funzionalità, lavorando su un'interfaccia e mappatura a tutte le entità rilevanti. – gareththegeek

+1

Ma questo significa un altro strato "mappatura" sopra EF che tradurrà le proprietà dell'interfaccia logica aziendale in proprietà EF reali. Questo livello di mappatura trasformerà anche le query. Non chiamo questo schema - lo chiamo su un'applicazione architettonica. –

+0

Forse troppo architettato, ma come evitare di copiare e incollare lo stesso codice in diversi oggetti del livello aziendale in modo che possano eseguire la stessa logica, ma utilizzando proprietà di entità con nomi diversi? – gareththegeek

Problemi correlati