Il y a quelques mois j'avais lu une série de message que je n'arrive
plus à trouver au sujet de la limitation d'entity famwork qui fait
qu'une entité nouvellement ajoutée à un contexte ne peut obtenir
automatiquement un clé primaire si celle-ci est un Guid.
Aillant codé une solution qui fonctionne je la post ici afin d'en faire
profiter le plus grand nombre.
Il s'agit en fait d'une méthode d’extension qui a pour mission d’ajouter
une entité nouvellement créé à un contexte de données et dans le cas où
celle-ci contient une clé primaire sous forme de Guid, elle créé un Guid
en testant que celui-ci n’est pas déjà utilisé. On se retrouve alors
avec un Guid généré automatiquement et ceci sans modifier ou altérer
notre modèle.
Voici mon code, je l'ai testé il marche très bien (j'ai prévu de mettre
la version vb sur les news dédiées à vb)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Entity;
using System.Data.Objects;
using System.Data.Objects.DataClasses;
using System.Reflection;
namespace mlEntity
{
public static class EntityTypeExtension
{
/// <summary>
/// Ajout d'un objet à un context et création automatique d'un
Guid pour une PK
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="context"></param>
/// <param name="entity"></param>
public static void Add<T>(this ObjectContext context, T entity)
where T : EntityObject
{
// Déterminer de la propriété qui correspond au jeux
d'entités de type T
PropertyInfo jeuProperty = context.GetType().GetProperties()
.FirstOrDefault(c => c.PropertyType ==
typeof(ObjectQuery<T>)
&& c.Name.StartsWith(typeof(T).Name));
if (jeuProperty != null)
{
// Déterminer la propriété du Type T qui est la clé
GUID (si il y en a une)
PropertyInfo keyProperty = typeof(T).GetProperties()
.FirstOrDefault(c =>
c.PropertyType == typeof(Guid)
&&
(c.GetCustomAttributes(typeof(EdmScalarPropertyAttribute),
true).FirstOrDefault() as EdmScalarPropertyAttribute).EntityKeyProperty
);
// Déterminer si le type T a un clé de type Guid
if (keyProperty != null)
{
// Recherche du jeu d'entités qui serra manipuler
pour tester le id
ObjectQuery<T> jeu = jeuProperty.GetValue(context,
null) as ObjectQuery<T>;
// Id qui serragénéré
Guid id;
// Méthode utilisée pour tester la validité de l'ID
Func<T, Boolean> test;
do
{
// Créer un Guid
id = Guid.NewGuid();
// Préparation du test
test = c =>
new Guid(keyProperty.GetValue(c,
null).ToString()) == id;
// Tester si le guid est déjà utilisé
} while (jeu.FirstOrDefault(test) != null);
// Utilisation de l'Id
keyProperty.SetValue(entity, id, null);
}
// Ajout de l'objet au context
context.AddObject(jeuProperty.Name, entity);
}
else
{
throw new Exception("Jeu d'entités introuvable dans le
context de données.");
}
}
}
}
--
Jérémy JEANSON
MCP
http://www.jjeanson.fr