使用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
表达式以处理{{1 }}设为Value
(尽管我不知道如何执行此步骤,但我认为Reflection不允许在左侧FooPropertyValue
有DateTime
的地方调用Expression.Equal
类型,右侧的Expression.Property
具有string
类型),将该生成的表达式传递给“ Where”,并希望该调用能够通过?
我问是因为,当您在SQL Server的Expression.Constant
列中存储动态值时,有可能(在运行时知道类型)在“ WHERE”子句中使用DateTime
和使查询速度更快(例如,在处理日期时也更有用)。可以使用EF Core吗?
编辑:实际上,使用CAST时查询速度不会很快,但是问题仍然存在,因为查询某些数据类型(例如nvarchar
,{{1 }}等使用CAST(Value as {VALUETYPE})
值。