我正在尝试在泛型中编写 LINQ 连接查询,但在识别外键时遇到了麻烦。PFB 代码。
我想识别表 U 中存在的外键,我可以将其用于比较操作。谢谢
var _tab = (from tblT in context.GetTable<T>()
join tblU in context.GetTable<U>()
on pk equals fk
select tblT).GetEnumerator();
我正在尝试在泛型中编写 LINQ 连接查询,但在识别外键时遇到了麻烦。PFB 代码。
我想识别表 U 中存在的外键,我可以将其用于比较操作。谢谢
var _tab = (from tblT in context.GetTable<T>()
join tblU in context.GetTable<U>()
on pk equals fk
select tblT).GetEnumerator();
您提到要“识别表 U 中存在的外键”。虽然您可以通过反射和某种约定来做到这一点,但它似乎是一个脆弱的解决方案。我建议您通过委托提供主/外键关系。
基本上,连接使用委托来检索主键和外键,LINQ 提供程序将其转换为连接子句。连接的每一侧的签名基本上是相同的,在你的例子中它是:Expression<Func<T, TKey>>
和Expression<Func<U, TKey>>
。重要的是要注意连接两侧的键类型必须相同。
无论您使用什么来调用此方法,都应该要求传入这些委托。它可能看起来像这样:
public class Query
{
public IEnumerable<T> GetData<T, U, TKey>(Expression<Func<T, TKey>> tKey, Expression<Func<U, TKey>> uKey)
{
Context context = new Context();
// using the extension method as the query expression had trouble figuring out the types
var data = context.GetTable<T>().Join(context.GetTable<U>(), tKey, uKey, (tblT, tblU) => tblT);
return data;
}
}
调用它看起来像这样:
var data = query.GetData<Person, Order, int>(person => person.Id, order => order.Orderer.Id);
我改进了@Gary.S 的答案。在这里,我改进了查询选择器以及如何在此处使用 where close。我认为这将对您有所帮助。
这是我更新的通用方法。
注意:AppDbContext 是我的 dbContext
public class MyGenMetClass
{
public async Task<IEnumerable<TResult>> FetchJonBy<TOuter, TInner, TKey, TResult>(Expression<Func<TOuter, TKey>> outerKeySelector, Expression<Func<TInner, TKey>> innerKeySelector, Expression<Func<TOuter, bool>> wherOuter, Expression<Func<TInner, bool>> wherInner, Expression<Func<TOuter, TInner, TResult>> resultSelector) where TOuter : class where TInner : class where TResult : class
{
try
{
using (AppDbContext db = new AppDbContext())
{
var data = await db.Set<TOuter>().Where(wherOuter).Join(db.Set<TInner>().Where(wherInner), outerKeySelector, innerKeySelector, resultSelector).ToListAsync();
return data;
}
}catch (Exception ex){
return null;
}
}
}
我的模型是这样的。
供应商模型类
public class SupplierModel
{
[Key]
public int SupplierId { get; set; }
public string Name { get; set; }
public int CategoryId { get; set; }
}
供应商类别
public class SupplierCatgory
{
[Key]
public int CategoryId { get; set; }
public string Category { get; set; }
public Boolean IsActive { get; set; } = true;
}
供应商视图模型类
public class SupplierViewModel
{
public int SupplierId { get; set; }
public string Name { get; set; }
public int CategoryId { get; set; }
public string Category { get; set; }
}
在这里我加入了 SupplierModel和SupplierCatgory并返回 SupplierViewModel
你可以这样打电话
var result =await new MyGenMetClass().FetchJonBy<SupplierModel,SupplierCatgory,int, SupplierViewModel>(s=> s.CategoryId,c=>c.CategoryId ,m=>m.IsAcvtive==true,c=>c.IsActive==true, (s, y) => new SupplierViewModel() { Name=s.Name,Category=y.Category} );