J'ai eu des problèmes similaires qui se sont produits dans EF6 (travaillèrent à EF4 sans transactions, EF 4 utilisé les transactions implicites avec la portée droite).
Juste en créant une nouvelle entité et en l'enregistrant n'a pas aidé dans mon cas (voir les commentaires des autres réponses, ils ont eu des problèmes similaires avec l'utilisation dc.SaveChanges()
uniquement pour la mise à jour automatique).
Consultez le code suivant (CustomerId
est la clé primaire avec auto-incrément):
public void UpdateCustomer(string strCustomerName, string strDescription)
{
using (var transaction = CreateTransactionScope())
{
MyCustomer tbl=null;
Func<MyCustomer, bool> 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'aide pour créer le bon contexte de transaction:
// 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 - d'où vous pouvez interroger l'ID max et ajouter 1 à id. Ce que je n'ai pas réussi à faire est de laisser le serveur SQL générer l'ID automatiquement, car EF me permet de ne pas omettre le CustomerId
lors de la création.
Pour en savoir plus sur la portée de la transaction, look here.
Ouais généralement à partir des pièces générées VS2010 vous devrez définir la valeur StoreGenerated dans le gros bloc supérieur de xml. Vous obtenez plusieurs clés primaires car, sauf si vous modifiez cela, EF génère l'ID pour vous, comme 0. – Rangoric
C'est fou qu'ils n'aient pas encore résolu ce bug omniprésent. C'est la version 4, venez sur l'équipe EF! – arviman
Souvent, les gens oublient de marquer la colonne avec une valeur d'incrément d'identité et automatique. EF récupère cela de la base de données. – arviman