使用Entity Framework Core 2.1动态转换为“ where”子句

时间:2018-09-09 18:39:10

标签: c# entity-framework-core

使用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不允许在左侧FooPropertyValueDateTime的地方调用Expression.Equal类型,右侧的Expression.Property具有string类型),将该生成的表达式传递给“ Where”,并希望该调用能够通过?

我问是因为,当您在SQL Server的Expression.Constant列中存储动态值时,有可能(在运行时知道类型)在“ WHERE”子句中使用DateTime使查询速度更快(例如,在处理日期时也更有用)。可以使用EF Core吗?

编辑:实际上,使用CAST时查询速度不会很快,但是问题仍然存在,因为查询某些数据类型(例如nvarchar,{{1 }}等使用CAST(Value as {VALUETYPE})值。

0 个答案:

没有答案