Использование EF Core 2.1.2. Для простейшего возможного примера, скажем, у меня есть класс с именем Foo
:
public class Foo
{
public int Id { get; set; }
public string Name { get; set; }
[ForeignKey("EntityId")]
public virtual ICollection<FooPropertyValue> PropertyValues { get; set; }
}
класс под названием FooPropertyValue
:
public class FooPropertyValue
{
public int PropertyId { get; set; }
[ForeignKey("PropertyId")]
public virtual FooProperty Property { get; set; }
public int EntityId { get; set; }
public string Value { get; set; }
}
и класс с именем FooProperty
:
public class FooProperty
{
public int Id { get; set; }
public string Name { get; set; }
public string CSharpType { get; set; } // System.Date, System.String, System.Int32 etc.
}
Так что это простая модель EAV.
Теперь возможно ли использовать это свойство CSharpType
при запросе этой модели?
Давайте рассмотрим этот запрос в качестве примера:
// Let's assume:
// the 'table' variable is IQueryable<Foo>
// the 'propertyId' is passed as a parameter
// the 'value' is passed as a parameter, and is of type System.String
// the 'CSharpType' for this property is 'System.DateTime'
// the requested property value exists, i.e. 'FirstOrDefault' will not return null
var result = table.Where(x => x.PropertyValues.FirstOrDefault(p => p.PropertyId == propertyId)).Value == value)
Этот запрос будет выполнен, но он будет возвращать что-то, только если сохраненное значение идентично переданному значению и, как плюс, будет медленным.
Можно ли преобразовать value
в DateTime
перед передачей его методу запроса, динамически построить выражение Where
, чтобы свойство Value
FooPropertyValue
считалось DateTime
(хотя я не не знаю, как сделать этот шаг, я думаю, что Reflection не позволит позвонить Expression.Equal
, где левая сторона Expression.Property
имеет тип string
и правая Expression.Constant
имеет тип DateTime
), передать, что построено Выражение «Где» и ожидаете, что вызов пройдет?
Я спрашиваю, потому что, когда вы храните динамические значения в столбце nvarchar
в SQL Server, возможно (когда тип известен во время выполнения), можно использовать CAST(Value as {VALUETYPE})
в предложении «WHERE» и сделать запрос несколько быстрее (но также более удобно при работе, например, с датами). Возможно ли это с помощью EF Core?
РЕДАКТИРОВАТЬ: На самом деле запрос не может быть быстрее при использовании CAST, но все еще остается вопрос, так как было бы трудно задавать некоторые типы данных, такие как decimal
, DateTime
и т. Д. используя string
значения.