Home > OS >  Create valid generic entity framework linq statement
Create valid generic entity framework linq statement

Time:10-08

I have a lots of different tables with code levels( 1 to 5, depending of which area the table represents). You can use these to search in different levels of granularity. So i have made a smaller examples of this. The tables in EF is downbelow and added to context 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);
    }
}

They trouble is here I really need to tell it has thoose codes the search for, but I cant cast it to Dim3(or Dim2 or Dim1) since then EF will respond with Expression... "LINQ to Entities only supports casting Entity Data Model primitive types” How do I cast it so I can search for the three paramers that I now know T has.

CodePudding user response:

Try using reflection:

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);
}
  • Related