实体框架中多个类似实体类型的常见查询

Imr*_*hid 7 c# linq entity-framework

我有一个场景,我在数据库中有3种类型的产品,所有产品都有自己独立的表(例如Product1,Product2Product3).几乎所有产品表都具有相同的模式.我需要在不同的表中获得不同类型的产品.

我目前有3种获取产品的方法,每种产品类型一种:

public List<Product1> GetProduct1Data() {
    //....
    context.Product1.Where(..).Tolist();
}

public List<Product2> GetProduct2Data() {
    //....
    context.Product2.Where(..).Tolist();
}

public List<Product3> GetProduct3Data() {
    //....
    context.Product3.Where(..).Tolist();
}
Run Code Online (Sandbox Code Playgroud)

在调用产品时,我有一个WebApi方法,它接受产品类型并调用相应的方法:

public IHttpActionResult GetProducts(ProductType product)
{ 
    ///....
    // Ii have to call repositories according to product parameter
}
Run Code Online (Sandbox Code Playgroud)

实体框架是否有任何方法可以选择只有一种方法的表?

Sef*_*efe 9

您可以使用带有接口约束的泛型方法.

当您拥有这些自动生成的POCO类时:

public partial class Product1 {
    public string Column1 {
        get;
        set;
    }

    public string Column2 {
        get;
        set;
    }
}


public partial class Product2 {
    public string Column1 {
        get;
        set;
    }

    public string Column2 {
        get;
        set;
    }
}


public partial class Product3 {
    public string Column1 {
        get;
        set;
    }

    public string Column2 {
        get;
        set;
    }
}
Run Code Online (Sandbox Code Playgroud)

您可以为实体类共有的属性创建一个接口...

interface IProduct {
    string Column1 {
        get;
        set;
    }

    string Column2 {
        get;
        set;
    }
}
Run Code Online (Sandbox Code Playgroud)

...您应用于生成的类(在新的代码文件中 - 类允许您这样做):

partial class Product1 : IProduct {};
partial class Product2 : IProduct {};
partial class Product3 : IProduct {};
Run Code Online (Sandbox Code Playgroud)

现在,您可以为查询创建通用方法.您可以将其作为扩展方法应用于您的DbSets:

static class ProductExtensions {
    public static List<T> GetProducts<T>(this DbSet<T> products)
        where T : IProduct {

        var productQry =
            from product in products
            where product.Column1 == "Example"
            select product;
        return productQry.ToList();
    }
}
Run Code Online (Sandbox Code Playgroud)

您可以在DbSets 上使用此扩展方法:

List<Product1> product1List = context.Product1s.GetProducts();
List<Product2> product2List = context.Product2s.GetProducts();
List<Product3> product3List = context.Product3s.GetProducts();
Run Code Online (Sandbox Code Playgroud)

您唯一的限制是表中的列确实需要具有相同的名称和类型.EF无法识别显式接口实现.另一方面,表格不必完全相同.您可以为部分列(必须匹配)定义接口,其余部分可以不同.