动态构建实体框架Linq to SQL Query

时间:2018-06-14 10:33:32

标签: c# sql-server entity-framework linq linq-to-sql

我正在尝试在linq to SQL中构建动态查询。简而言之,我想解决的问题如下:

我们有一个现有的SQL Server数据库,其中包含许多我们希望能够一般搜索的表。这是一个遗留数据库,因此我们首先使用实体​​框架数据(不是代码优先)。 在我们的数据库中,我们还有一个元数据表,其中包含其他表的表名和列名,以及哪些列是可搜索的。

例如,我们可能会有一个名为' Vehicles'使用名为' Vehicle_Id'的PK列,以及名为' Type'的可搜索列。和'颜色'。我们的元数据表将包含列的类型'类型'和'颜色'将它们标记为可搜索。

Vehicle实体的EF模型和映射看起来像这样:

public class Vehicle
{
    public int Id { get; set; }
    public string Type { get; set; }
    public string Colour { get; set; }
}

public class VehicleMap : EntityTypeConfiguration<Vehicle>
{
    public VehicleMap()
    {
        This.ToTable("VEHICLES");
        This.HasKey(k => k.Id);
        This.Property(p => p.Id).HasColumnName("VEHICLE_ID");
        This.Property(p => p.Type).HasColumnName("TYPE");
        This.Property(p => p.Colour).HasColumnName("COLOUR");
    }
}

用户然后定义搜索要求(例如,&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39; &#39;蓝色&#39)。这些搜索要求基于列名称。

我希望能够根据元数据表中定义的字段名称动态构建查询,如下所示:

var query = from v in context.Vehicles select v.Id;
foreach (var criterion in criteria)
{
    var fieldName = criterion.Field;  // Database field name, e.g. "TYPE"
    var value = criterion.Value;      // Search value, e.g. "CAR"

    var filter = [Filter based on field/value]

    results = query.Where(filter).ToList();
    // do something with results...
}

目前,我认为我在中途使用以下扩展方法,该方法从EF上下文获取给定表的实体映射。我迷失的是然后根据字段名称找到字段(例如&#39; COLOR&#39;)并基于此构建过滤器。

public static EntityType GetTableMapping(this DbContext context, string tableName)
{
    var objectContext = ((IObjectContextAdapter)context).ObjectContext;
    var storageMetadata = ((EntityConnection)objectContext.Connection).GetMetadataWorkspace().GetItems(DataSpace.SSpace);
    var entityProps = storageMetadata.Where(s => s.BuiltInTypeKind == BuiltInTypeKind.EntityType).Select(s => s as EntityType);
    return (from m in entityProps where string.Compare(m.Name, tableName, StringComparison.OrdinalIgnoreCase) == 0 select m).SingleOrDefault();
}

0 个答案:

没有答案