2010-03-01 3 views
1

Disons que je créé un nouveau produit comme celui-ci:Comment mettre à jour une entité de nouvelle créée entité détachée

Product p=new Product(){ Id= 2,Name="some name"}; 

Ma variable produit n'a jamais été attaché à un contexte de données, comment puis-je joindre cette entité pour que mon produit existant dans la base de données avec Id = 2 obtient mise à jour avec le nom de mon produit détaché?

Répondre

0

J'espère que quelque chose de similaire fonctionnerait

Datacontext db = new Datacontext(); // replace with your DataContext 
Product originalProduct = 
     db.Products.Single(p => p.Id == 2); // get product with Id 2 

originalProduct.Name = "SomeName"; // only reset Name prop 
originalProduct = p;    // or you may assign p to originalProduct 
db.SubmitChanges();     // submit changes to DB 
+0

Cela devrait certainement travailler mais pourrait être douloureux pour copier toujours sur les propriétés. Dans NHibernate, ils ont une construction appelée Reattach qui vous permet de spécifier qu'il s'agit d'un objet existant dans la base de données. Je ne suis pas sûr que L2S l'ait ou non. –

+0

bien sûr, mais op utilise L2S –

0

Un peu plus facile solution serait de mettre en œuvre l'interface ICloneable sur l'entité que vous souhaitez travailler comme ça. Ensuite, tout ce que vous avez à faire est d'appeler Clone() dans l'entité 'originale' que vous avez extraite de la base de données.

Exemple:

class Product : ICloneable 
{ 
    public virtual int Id { get; private set; } 
    public virtual string Name { get; set; } 

    public object Clone() 
    { 
     return new Product() { Id=this.Id, Name=this.Name }; 
    } 
} 

Et tout ce que vous devez faire est:

Datacontext db = new Datacontext(); // replace with your DataContext 
Product originalProduct = 
     db.Products.Single(p => p.Id == 2); // get product with Id 2 

db.originalProduct = p.Clone() 
db.SubmitChanges(); 

Edit: je suis tombé sur le même problème au travail, jusqu'à la solution la plus élégant trouvé était de construire une méthode d'extension qui reçoit l'entité nouvellement créée, dans votre cas Product, et copie ses propriétés (à l'exception de l'identificateur) à l'entité que vous avez extrait du DataContext.

J'ai copié toutes les propriétés via Reflection, de cette façon, si je mets à jour l'entité, alors ma méthode d'extension fonctionnera toujours.

Espérons que cela vous aide aussi.

Si vous trouvez une solution plus élégante à ce problème, je voudrais entendre :)

+0

db.originalProduct ne semble pas correct ... Et quand vous affectez p.Clone() à originalProduct, il n'est plus 'attaché' au contexte, donc il ne sera pas conservé . –

+0

Oh, vous avez raison, je n'y ai pas réfléchi ... Je vais vérifier et essayer de le réparer. J'ai juste rencontré le même problème au travail, donc je dois penser à une bonne solution, et quand je le fais, je vais le réparer! :) Merci! – gillyb

+1

Si vous souhaitez ignorer l'utilisation de la réflexion, vous pouvez également utiliser MappingSource de DataContext pour copier les valeurs dans une nouvelle version clonée. De cette façon, il va seulement copier les propriétés qui se rapportent spécifiquement à votre base de données. – rossisdead

0

Juste pour ajouter à la poste gillyb et le commentaire je suis parti là-bas. Un moyen très facile pour le clonage de votre entité est de le faire:

Private Function CloneEntity(Of TEntity)(ByVal entity As TEntity) As TEntity 

    Dim dataContext As New DataContext() 
    Dim entityType As System.Type = GetType(TEntity) 

    ' If the purpose of the clone is just to attach it the existing entity to a new 
    ' DataContext, you can use IdentityMembers in place of PersistantDataMembers. Setting 
    ' only the IdentityMembers is enough to allow for attaching the clone as an "originaL" 
    ' entity to the DataContext. 
    Dim dataMembers = dataContext.Mapping.GetTable(entityType).RowType.PersistentDataMembers 

    Dim clone As TEntity ' Do something here to create an entity of the desired type. 
    Dim boxedClone As Object = clone 

    For Each dm In dataMembers 

     ' Depending on how your ColumnAttribute is set, you would use StorageAccessor if 
     ' the Storage property is set. Otherwise, you would use MemberAccessor instead. 
      dm.StorageAccessor.SetBoxedValue(boxedClone, dm.StorageAccessor.GetBoxedValue(entity)) 
    Next 

    Return clone 

End Function 

Ensuite, vous juste besoin de faire ceci:

Dim dataContext As New DataContext() 
dataContext.GetTable(Of Object)().Attach(entityToUpdate, CloneEntity(entityToUpdate)) 
dataContext.SubmitChanges() 
Questions connexes