¿Cómo usar las propiedades heredadas en las expresiones EF Core?

Necesitamos construir expresiones para EF de forma dinámica. Por ejemplo crear modelos de prueba:

public class TestBase { public int Id { get; set; } } public class TestCard : TestBase { public Guid Guid { get; set; } } 

Crear una consulta linq:

 var q = from card in Context.hlt_disp_Card select new TestCard { Id = card.disp_CardID, Guid = card.Guid }; 

Normal usando expresiones:

 Expression<Func> ex1 = card => card.Id == 1030; q.Where(ex1).ToList(); 

Necesitamos crear una expresión de cualquier tipo y siempre tenemos un nombre de cadena de propiedad, por lo que intentamos construirlo de esta manera:

 var e = Expression.Parameter(typeof(TestCard), "card"); Expression bin = Expression.Property(e, "Id"); bin = Expression.Equal(bin, Expression.Constant(1030)); var ex2 = Expression.Lambda<Func>(bin, e); q.Where(ex2).ToList(); 

Pero tenemos una advertencia:

Microsoft.EntityFrameworkCore.Query.Internal.SqlServerQueryComstacktionContextFactory [8] La expresión LINQ ‘(new TestCard () {Id = [card] .disp_CardID, Guid = [card] .Guid} .Id == 1030)’ no se pudo traducir y serán evaluados localmente. Para configurar esta advertencia, use la API DbContextOptionsBuilder.ConfigureWarnings (id de evento ‘RelationalEventId.QueryClientEvaluationWarning’). ConfigureWarnings se puede usar al anular el método DbContext.OnConfiguring o al usar AddDbContext en el proveedor de servicios de la aplicación.

Verificamos el SQL resultante en el generador de perfiles y obtuvimos estos resultados: q.Where (ex1) .ToList (); construido para

 SELECT [card].[disp_CardID], [card].[Guid] FROM [hlt_disp_Card] AS [card] WHERE [card].[disp_CardID] = 1030 

y q.Where (ex2) .ToList (); construido para

 SELECT [card].[disp_CardID], [card].[Guid] FROM [hlt_disp_Card] AS [card] 

¡Y si trato de construir un filtro para una propiedad no heredada (por ejemplo, Guid) mi manera funciona bien!

Versión Core EF: 1.0.1

¿Cómo resolver este problema?

Wow, esto suena como otro error de EF Core (también ocurre en v.1.1.0 (versión)).

La única diferencia entre las dos expresiones es el tipo ReflectedType del Member expresión de acceso a la propiedad.

Puedes arreglarlo de esta manera:

 // ... var p = e.Type.GetProperty("Id"); if (p.ReflectedType != p.DeclaringType) p = p.DeclaringType.GetProperty(p.Name); Expression bin = Expression.MakeMemberAccess(e, p); // ... 

pero es extraño tener tal requisito, sugeriría informar el problema a EF Core GitHub .