C #, framework d’entités, incrémentation automatique

J’apprends Entity Framework sous VC # 2010.

J’ai créé un tableau simple à des fins d’apprentissage. L’un des champs est un entier de type “id”, identity étant défini sur true. J’ai généré Entity Data Model à partir de cette table et l’ai connecté à dataGridView. Le problème est qu’il n’incrémente pas automatiquement – chaque ligne insérée veut être id = 0 (ce qui est bien sûr impossible, car id doit être unique)

Qu’est-ce que je fais mal? Comment dois-je configurer EF ou la firebase database SQL elle-même?

Vérifiez dans votre modèle EDMX que l’atsortingbut StoreGeneratedPattern du champ auto-incrémenté est défini sur “Identity”. Ainsi, EF sait que les numéros automatiques sont gérés par la firebase database.

Ici, cela s’explique mieux: Numéro automatique avec Entity Framework

L’identité n’est pas définie ni incrémentée simplement en l’ajoutant au jeu d’entités … L’entité n’est pas réellement enregistrée dans la firebase database jusqu’à ce que vous appeliez context.SaveChanges () …

db.AddToUserSet(user);//Added to EF entity collection db.SaveChanges();//INSERT executed in db, Identity set and incremented. 

Assurez-vous de sauvegarder vos entités dans la firebase database avant d’essayer de lire la valeur de l’ID incrémenté automatiquement.

Votre identifiant ne sera pas défini par incrémentation automatique avant sa première sauvegarde dans la firebase database.

Oui. LINQ to SQL se comporte de la même manière. L’identifiant ne sera pas défini tant qu’il n’aura pas été enregistré dans la firebase database. En attendant, tous les identifiants seront nuls (comme vous l’avez déjà vu).

J’avais des problèmes similaires, qui se produisaient dans EF6 (fonctionnait dans EF4 sans transaction, EF 4 utilisait des transactions implicites avec la bonne étendue).

Le simple fait de créer une nouvelle entité et de l’enregistrer n’a pas aidé dans mon cas (voir les commentaires des autres réponses, ils avaient des problèmes similaires avec l’utilisation de dc.SaveChanges() uniquement pour la mise à jour automatique).

Considérez le code suivant ( CustomerId est la clé primaire avec incrémentation automatique):

 public void UpdateCustomer(ssortingng strCustomerName, ssortingng strDescription) { using (var transaction = CreateTransactionScope()) { MyCustomer tbl=null; Func selectByName=(i => i.CustomerName.Equals(strCustomerName)); var doesRecordExistAlready = dc.MyCustomers.Any(selectByName); if (doesRecordExistAlready) { // Updating tbl=dc.MyCustomers.Where(selectByName).FirstOrDefault(); tbl.Description=strDescription; } else { // Inserting tbl=new MyCustomer(); var maxItem= dc.MyCustomers.OrderByDescending(i => i.CustomerId).FirstOrDefault(); var newID = maxItem==null ? 1 : maxItem.CustomerId+1; tbl.CustomerId=newID; tbl.CustomerName=strCustomerName; tbl.Description=strDescription; dc.MyCustomers.AddObject(tbl); } dc.SaveChanges(); // save all changes consistently transaction.Complete(); // commit } } 

Et la fonction d’assistance pour créer le bon contexte de transaction est:

 // creates the right transaction scope public static System.Transactions.TransactionScope CreateTransactionScope() // needs to add ref: System.Transactions { var transactionOptions = new TransactionOptions { IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted, Timeout = new TimeSpan(0,0,10,0,0) //assume 10 min is the timeout time }; var scopeOption=TransactionScopeOption.RequiresNew; var scope = new System.Transactions.TransactionScope(scopeOption, transactionOptions); return scope; } 

L’astuce est ici, pour permettre la lecture non validée – vous pouvez donc interroger l’ID max et append 1 à id. Ce que je n’ai pas réussi à faire, c’est de laisser le serveur SQL générer automatiquement l’ID, car EF me permet de ne pas omettre l’ID CustomerId lors de la création.

Pour en savoir plus sur la scope de la transaction, regardez ici.