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.
You could try writing an extension method onto your
DataContextobject that facilitates the pulling of records from the database by their Primary Key, as outlined by Chris Sainty in his blog post LINQ to SQL: Generic Primary Key function :Then call the method by way of:
You might also want to have a look at Denis Troller’s answer as an alternative.