创建有效的通用 Entity Framework linq 语句
Create valid generic Entity Framework linq statement
我有很多不同的 table 代码级别(1 到 5,具体取决于 table 代表的区域)。您可以使用这些以不同的粒度级别进行搜索。所以我做了一个较小的例子。 EF 中的 table 显示在此处并添加到 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 Queryable = dbcontext.Set<T>().AsQueryable();
if (typeof(Dim3).IsAssignableFrom(typeof(T)))
{
// They trouble is here
return Queryable.Cast<Dim3>().Any(o => o.Dim3Code == code || o.Dim2Code == code || o.Dim1Code == code);
}
else if (typeof(Dim2).IsAssignableFrom(typeof(T)))
{
// also here
return Queryable.Cast<Dim2>().Any(o => o.Dim2Code == code || o.Dim1Code == code);
}
else
{
// also here
return Queryable.Cast<Dim1>().Any(o => o.Dim1Code == code);
}
}
他们的麻烦就在这里我真的需要告诉它有这个搜索代码,但我不能将它转换为 Dim3(或 Dim2 或 Dim1),因为那时 EF 将响应表达式...“LINQ to Entities only支持转换实体数据模型原始类型”
如何转换它以便搜索我现在知道 T 具有的三个参数。
尝试使用反射:
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);
}
我有很多不同的 table 代码级别(1 到 5,具体取决于 table 代表的区域)。您可以使用这些以不同的粒度级别进行搜索。所以我做了一个较小的例子。 EF 中的 table 显示在此处并添加到 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 Queryable = dbcontext.Set<T>().AsQueryable();
if (typeof(Dim3).IsAssignableFrom(typeof(T)))
{
// They trouble is here
return Queryable.Cast<Dim3>().Any(o => o.Dim3Code == code || o.Dim2Code == code || o.Dim1Code == code);
}
else if (typeof(Dim2).IsAssignableFrom(typeof(T)))
{
// also here
return Queryable.Cast<Dim2>().Any(o => o.Dim2Code == code || o.Dim1Code == code);
}
else
{
// also here
return Queryable.Cast<Dim1>().Any(o => o.Dim1Code == code);
}
}
他们的麻烦就在这里我真的需要告诉它有这个搜索代码,但我不能将它转换为 Dim3(或 Dim2 或 Dim1),因为那时 EF 将响应表达式...“LINQ to Entities only支持转换实体数据模型原始类型”
如何转换它以便搜索我现在知道 T 具有的三个参数。
尝试使用反射:
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);
}