【问题标题】:Create valid generic Entity Framework linq statement创建有效的通用实体框架 linq 语句
【发布时间】:2021-10-04 12:32:54
【问题描述】:

我有很多不同的表,代码级别(1 到 5,取决于表代表的区域)。您可以使用它们以不同的粒度级别进行搜索。所以我做了一个较小的例子。 EF 中的表在下方并添加到上下文 dbcontext。

public interface IDim1
{
    int Id { get; set; }
    string Dim1Code { get; set; }
}

public class Dim1 : IDim1
{
    public int Id { get; set; }
    public string Dim1Code { get; set; }
}

public interface IDim2 : IDim1
{
    string Dim2Code { get; set; }
}

public class Dim2 : IDim2
{
    public string Dim2Code { get; set; }
}

public interface IDim3 : IDim2
{
    string Dim3Code { get; set; }
}

public class Dim3 : Dim2, IDim3
{
    public string Dim3Code { get; set; }
}

public class House : Dim2
{
    public string House { get; set; }
}

public class Car : Dim1
{
    public string Car { get; set; }
}

public class Work : Dim3
{
    public string Employeer { get; set; }
}

public bool DimensionCodeExists<T>(string code) where T : Dim1
{
    var Querable = dbcontext.Set<T>().AsQuerable();

    if (typeof(Dim3).IsAssignableFrom(typeof(T)))
    {
        //  They trouble is here
        return Querable.Cast<Dim3>().Any(o => o.Dim3Code == code || o.Dim2Code == code || o.Dim1Code == code);
    }
    else if (typeof(Dim2).IsAssignableFrom(typeof(T)))
    {
        // also here
        return Querable.Cast<Dim2>().Any(o => o.Dim2Code == code || o.Dim1Code == code);
    }
    else
    {
        // also here
        return Querable.Cast<Dim1>().Any(o => o.Dim1Code == code);
    }
}

他们的麻烦就在这里,我真的需要告诉它有要搜索的代码,但我不能将它转换为 Dim3(或 Dim2 或 Dim1),因为那时 EF 会以 Expression 响应...“LINQ to Entities 仅支持转换实体数据模型原语类型” 如何转换它,以便我可以搜索我现在知道 T 具有的三个参数。

【问题讨论】:

    标签: .net generics casting entity-framework-6 linq-to-entities


    【解决方案1】:

    尝试使用反射:

    private bool Dim3CodeExists<T>(string code) where T : Dim3
    {
        return dbcontext.Set<T>().Any(o => o.Dim3Code == code || o.Dim2Code == code || o.Dim1Code == code);
    }
    
    private bool Dim2CodeExists<T>(string code) where T : Dim2
    {
        return dbcontext.Set<T>().Any(o => o.Dim2Code == code || o.Dim1Code == code);
    }
    
    private bool Dim1CodeExists<T>(string code) where T : Dim1
    {
        return dbcontext.Set<T>().Any(o => o.Dim1Code == code);
    }
    
    public bool DimensionCodeExists<T>(string code) where T : Dim1
    {
        if (typeof(Dim3).IsAssignableFrom(typeof(T)))
        {
            var openMethod = typeof(YourClass).GetMethod(nameof(Dim3CodeExists), BindingFlags.NonPublic | BindingFlags.Instance);
            var boundMethod = openMethod.MakeGenericMethod(typeof(T));
            return (bool)boundMethod.Invoke(this, new[] { code });
        }
        
        if (typeof(Dim2).IsAssignableFrom(typeof(T)))
        {
            var openMethod = typeof(YourClass).GetMethod(nameof(Dim2CodeExists), BindingFlags.NonPublic | BindingFlags.Instance);
            var boundMethod = openMethod.MakeGenericMethod(typeof(T));
            return (bool)boundMethod.Invoke(this, new[] { code });
        }
        
        return Dim1CodeExists<T>(code);
    }
    

    【讨论】:

    • 这行得通。有点难过,我需要反思来解决这个问题,但它确实有效。
    猜你喜欢
    • 2013-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-14
    • 1970-01-01
    • 2017-07-07
    • 1970-01-01
    相关资源
    最近更新 更多