Bonjour,

Je dispose d'une bdd SQL mappée avec un fichier .dbml (LINQ to SQL) sur lequel j'ai réalisé une classe de synchronisation automatique entre deux bases de données (prod et dev). Bien entendu, je ne veux pas tout re-coder à chaque fois donc j'ai mangé beaucoup de génériques et autres réflexions.

J'ai presque réussi à en venir à bout mais j'ai encore besoin de définir une méthode abstraite qui m'oblige donc à la retaper pour chaque table : Celle qui fait le select sur la PK. Le problème est donc de réussir à déterminer la PK de la table pour faire le select dynamiquement et retourner l'élément si trouvé.

J'en suis donc arrivé à ceci :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
 
public static T GetByPk<T>(DataContext context, T row) where T : class
{
  Table<T> table = context.GetTable<T>();
  MetaTable 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));
 
  ParameterExpression 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);
}
Je cherche donc la ligne "row" dans la table "T" du contexte "context".

Comme vous pouvez le voir, j'arrive à récupérer les élément de la clé primaire et à lancer le test mais malheureusement, la méthode Expression.Property n'accepte que le nom d'un élément et non pas celui de plusieurs éléments en même temps.

Quelqu'un aurait une idée ?