Is it possible to perform a LinQ select by PK dynamically ?
Something like that :
public T FindByPK(IEnumerable<T> table, T itemToFind)
{
}
T is a mapping from table (LinQ to SQL autogenerated).
I tryed using reflection but I don't know how to get the attribute "IsPrimaryKey" and then perform the LinQ because sometimes the PK contains more than one column.
EDIT after Answer by chridam
So, I can now do a GetByPK but it assumes that the PK is only one column...
public static class DataContextHelpers
{
public static T GetByPk<T>(this DataContext context, object pk) where T : class {
var table = context.GetTable<T>();
var mapping = context.Mapping.GetTable(typeof(T));
var pkfield = mapping.RowType.DataMembers.SingleOrDefault(d => d.IsPrimaryKey);
if (pkfield == null)
throw new Exception(String.Format("Table {0} does not contain a Primary Key field", mapping.TableName));
var param = Expression.Parameter(typeof(T), "e");
var predicate = Expression.Lambda<Func<T, bool>>(Expression.Equal(Expression.Property(param, pkfield.Name), Expression.Constant(pk)), param);
return table.SingleOrDefault(predicate);
}
}
I changed the code like this to be able to get all columns of the primary keys and also, the object pk has to be a row of the table (because I don't know what are the pk columns)
public static T GetByPk<T>(this DataContext context, T row) where T : class
{
var table = context.GetTable<T>();
var mapping = context.Mapping.GetTable(typeof(T));
var pkfield = mapping.RowType.DataMembers.Where(d => d.IsPrimaryKey);
if (!pkfield.Any())
throw new Exception(String.Format("Table {0} does not contain a Primary Key field", mapping.TableName));
var param = Expression.Parameter(typeof(T), "e");
var predicate = Expression.Lambda<Func<T, bool>>(Expression.Equal(Expression.Property(param, pkfield??), Expression.Property(param, row??)), param);
return table.SingleOrDefault(predicate);
}
So, I am stuck at Expression.Property who need only one property and not a group of many.