Reputation: 503
I'm trying to write LINQ join query In generics, but having trouble in identifying the Foreign Key. PFB code.
I want to identify the Foreign Key present in table U, which I can use it for the comparison operation.Thanks
var _tab = (from tblT in context.GetTable<T>()
join tblU in context.GetTable<U>()
on pk equals fk
select tblT).GetEnumerator();
Upvotes: 2
Views: 2513
Reputation: 2216
I have improved @Gary.S answer. here I improved regarding query selector and how to use where close in here. I think this will help full for you.
this is the generic method which I updated.
Note : AppDbContext is my 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;
}
}
}
and my model like this.
SupplierModel Class
public class SupplierModel
{
[Key]
public int SupplierId { get; set; }
public string Name { get; set; }
public int CategoryId { get; set; }
}
SupplierCatgory Class
public class SupplierCatgory
{
[Key]
public int CategoryId { get; set; }
public string Category { get; set; }
public Boolean IsActive { get; set; } = true;
}
SupplierViewModel Class
public class SupplierViewModel
{
public int SupplierId { get; set; }
public string Name { get; set; }
public int CategoryId { get; set; }
public string Category { get; set; }
}
here I joined SupplierModel and SupplierCatgory and return SupplierViewModel
And you can call like this
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} );
Upvotes: 0
Reputation: 7131
You mention that you want to "identify the Foreign Key present in table U". While you may be able to do that via reflection and some sort of convention it seems like it would be a brittle solution. I would suggest that you provide the primary/foreign key relationship via a delegate.
Basically a join uses a delegate for retrieving the primary and foreign keys and the LINQ provider translates that into the join clause. The signature of each side of the join is basically the same, in your example it would be: Expression<Func<T, TKey>>
and Expression<Func<U, TKey>>
. It is important to note the the key type must be the same for both sides of the join.
Whatever you use to call this method should require that these delegates be passed in. It might look something like this:
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;
}
}
Calling it would look like this:
var data = query.GetData<Person, Order, int>(person => person.Id, order => order.Orderer.Id);
Upvotes: 6