2009-03-20 8 views
6

J'ai plusieurs classes d'entités que j'utilise pour analyser des fichiers texte de largeur fixe et utiliser Linq to SQL. J'utilise ces classes pour analyser les données provenant de ces fichiers texte, et les comparer aux données de la base de données.Meilleure façon de mettre à jour dans Linq To SQL

Une de ces entités a beaucoup de propriétés, et je ne veux pas perdre de temps à définir chaque propriété individuelle sur l'objet résultat Linq.

Y at-il un moyen de dire à Linq "Voici mon objet, utilisez-le pour mettre à jour l'enregistrement"? Voici ce code que je travaille sur:

 
if (partialContent.MonthlyAddChange == "A") 
    { 
     bookContentTable.InsertOnSubmit(partialContent); 
    } 
    else if (partialContent.MonthlyAddChange == "C") 
    { 
     var query = from bookContent in bookContentTable 
        where bookContent.EAN == partialContent.EAN 
        select bookContent; 

     if (query != null) 
     { 
      // Do something with query.First() 
     } 
    } 
} 

Est-il préférable de supprimer l'enregistrement et faire une InsertOnSubmit() dans ce cas?

+3

La variable "query" n'est jamais nulle, la séquence peut être vide, mais pas null. –

Répondre

2

Je pense que le concept de modification d'un enregistrement est différent de Suppression et insertion un nouveau. Fondamentalement, je pense qu'un ORM devrait abstraire la génération de clé primaire et d'autres choses connexes. En supprimant et en insérant, vous pourriez supprimer l'intégrité de l'enregistrement (en émettant probablement une nouvelle clé primaire, rendant les entités référencées invalides, etc.). Je suggère de mettre à jour l'enregistrement chaque fois que l'action que vous prenez est conceptuellement une mise à jour.

0

Je ne voudrais pas supprimer/recréer. En supposant que les deux objets ont la même interface par rapport aux propriétés que vous voulez mettre à jour, j'utiliserais la réflexion et copierais les valeurs de la modification dans l'objet existant. Si l'une des valeurs est différente de l'original, l'enregistrement sera marqué comme devant être mis à jour et SubmitChanges s'en chargera.

Par exemple (avec peu de contrôle d'erreur):

foreach (var bookInfo in bookContent.GetType().GetProperties()) 
{ 
    var partialInfo = partialContent.GetType().GetProperty(bookInfo.Name); 
    if (partialInfo != null) 
    { 
     bookInfo.SetValue(partialInfo.GetValue(partialContent, null)); 
    } 
} 

Si vous saviez qu'ils étaient du même type que vous pouvez réutiliser la première PropertyInfo au lieu d'obtenir un nouveau pour partialContent.

1

Je pense que vous pourriez utiliser quelque chose comme DataContext.Table.Attach (record, true), puis DataContext.SubmitChanges(). Mais je ne l'ai pas totalement étoffé ...

Alors maintenant j'ai fait un test. Cela ne fonctionnera que si vous n'avez pas besoin de vérifier la concurrence (c'est-à-dire que vous êtes le seul à mettre à jour la table).

Voilà ma table

People 
PersonID int 
FirstName varchar(50) 
LastName varchar(50) 

Je peuplaient la table avec l'enregistrement suivant

> PersonID  FirstName LastName 
> 1   Jason  Punyon 

J'ai créé un DataContext LINQ2SQL avec juste ce tableau appelé PeopleDataContext et sur tous les biens de la classe Les gens que je mets la propriété UpdateCheck de chaque propriété d'enregistrement à Jamais.

Voici le code:

static void Main(string[] args) 
{ 
    var p = new People(); 
    p.PersonID = 1; 
    p.FirstName = "Jason"; 
    p.LastName = "This is a new last name"; 


    using (var db = new PeopleDataContext()) 
    { 
     db.Peoples.Attach(p, true); 
     db.SubmitChanges(); 
    } 
} 

Et ça marche avec succès. Pas de réflexion ou quoi que ce soit, mais comme je l'ai dit, vous perdez la vérification de la concurrence.

+0

Pouvez-vous faire en sorte que la propriété de vérification des mises à jour change en lettres énormes, car c'est essentiellement la réponse si vous n'avez pas besoin de vous soucier de la simultanéité –

1

Vaut-il mieux supprimer l'enregistrement et faire un InsertOnSubmit() dans ce cas?

Non, certainement pas - il suffit de considérer l'intégrité référentielle que tout bon concept de base de données stable devrait utiliser. Si votre enregistrement est déjà utilisé par d'autres lignes, vous ne pouvez pas simplement le supprimer et le réinsérer - vous casseriez ces contraintes d'intégrité.

Si vous modifiez simplement quelques valeurs, mettez à jour la ligne existante, beaucoup plus facilement et de manière plus cohérente.

Marc

Questions connexes