Ho un modello db che voglio filtrare (durante il runtime) su diversi attributi. Per questo ho ciascuno dei metodi che eseguono una clausola "where" a seconda dell'attributo e restituiscono un IQueryable. Il fatto è che la clausola non può essere tradotta in SQL, quindi la query viene eseguita senza istruzioni "WHERE", restituisce l'intera tabella e il server sta eseguendo il filtro, che è lento e costoso.
Dai registri, ricevo un messaggio:
Microsoft.EntityFrameworkCore.Query: Avviso: L'espressione LINQ 'dove (nuovo EntityId ([ed] .EntityId) .Id == __entityId_Id_1)' non è stata tradotta e verrà valutata localmente.
La mia domanda è: sono sulla strada giusta qui o no? E se sì, dove dovrei guardare dopo?
Funzioni principali)
public static EntityDataDTO GetEntityByKey(this IQueryable<EntityDTO> query, IEntityId entityId, EntityTypeDTO type, string key)
{
return query
.HasEntity(entityId)
.HasType(type)
.HasKey(key)
.FirstOrDefault();
}
public static EntityDataDTO GetEntity(this IQueryable<EntityDTO> query, IEntityId entityId, EntityTypeDTO type)
{
return query
.HasEntity(entityId)
.HasType(type)
.FirstOrDefault();
}
sottofunzioni
public static IQueryable<EntityDDTO> HasType(this IQueryable<EntityDTO> query, EntityTypeDTO type)
{
return query.Where(ed => ed.Type == type);
}
public static IQueryable<EntityDTO> HasEntity(this IQueryable<EntityDTO> query, IEntityId entityId)
{
return query.Where(ed => ed.EntityId.Id == entityId.Id);
}
EntityDTO
public class EntityDTO
{
public int Id { get; set; }
public EntityTypeDTO Type { get; set; }
public string Key { get; set; }
public string Value { get; set; }
public IEntityId EntityId { get; set; }
public IPartnerId PartnerId { get; set; }
}
Non vedo alcun problema con nessuno dei codici che hai pubblicato. Tuttavia, hai trascurato di pubblicare la definizione del tuo metodo HasKey
, quindi HasKey
che il problema sia effettivamente lì.
In ogni caso, l'avviso ti dice esattamente qual è il codice problematico: new EntityId(ed.EntityId).Id
. Trova quel pezzetto di codice e correggilo. Qualcosa come una chiamata a un nuovo tipo non può essere tradotto in SQL, quindi EF deve eseguirlo in memoria. Tecnicamente, puoi procedere e consentire a EF di farlo. Tuttavia, questo è generalmente un segnale che stai per eseguire query inefficienti, quindi dovresti cercare un modo migliore che non implichi la necessità di eseguire quella parte della query in memoria.