it-swarm.com.de

SqlException von Entity Framework - Neue Transaktion ist nicht zulässig, da in der Sitzung andere Threads ausgeführt werden

Ich erhalte gerade diesen Fehler:

System.Data.SqlClient.SqlException: Neue Transaktion ist nicht zulässig, da in der Sitzung andere Threads ausgeführt werden.

während Sie diesen Code ausführen:

public class ProductManager : IProductManager
{
    #region Declare Models
    private RivWorks.Model.Negotiation.RIV_Entities _dbRiv = RivWorks.Model.Stores.RivEntities(AppSettings.RivWorkEntities_connString);
    private RivWorks.Model.NegotiationAutos.RivFeedsEntities _dbFeed = RivWorks.Model.Stores.FeedEntities(AppSettings.FeedAutosEntities_connString);
    #endregion

    public IProduct GetProductById(Guid productId)
    {
        // Do a quick sync of the feeds...
        SyncFeeds();
        ...
        // get a product...
        ...
        return product;
    }

    private void SyncFeeds()
    {
        bool found = false;
        string feedSource = "AUTO";
        switch (feedSource) // companyFeedDetail.FeedSourceTable.ToUpper())
        {
            case "AUTO":
                var clientList = from a in _dbFeed.Client.Include("Auto") select a;
                foreach (RivWorks.Model.NegotiationAutos.Client client in clientList)
                {
                    var companyFeedDetailList = from a in _dbRiv.AutoNegotiationDetails where a.ClientID == client.ClientID select a;
                    foreach (RivWorks.Model.Negotiation.AutoNegotiationDetails companyFeedDetail in companyFeedDetailList)
                    {
                        if (companyFeedDetail.FeedSourceTable.ToUpper() == "AUTO")
                        {
                            var company = (from a in _dbRiv.Company.Include("Product") where a.CompanyId == companyFeedDetail.CompanyId select a).First();
                            foreach (RivWorks.Model.NegotiationAutos.Auto sourceProduct in client.Auto)
                            {
                                foreach (RivWorks.Model.Negotiation.Product targetProduct in company.Product)
                                {
                                    if (targetProduct.alternateProductID == sourceProduct.AutoID)
                                    {
                                        found = true;
                                        break;
                                    }
                                }
                                if (!found)
                                {
                                    var newProduct = new RivWorks.Model.Negotiation.Product();
                                    newProduct.alternateProductID = sourceProduct.AutoID;
                                    newProduct.isFromFeed = true;
                                    newProduct.isDeleted = false;
                                    newProduct.SKU = sourceProduct.StockNumber;
                                    company.Product.Add(newProduct);
                                }
                            }
                            _dbRiv.SaveChanges();  // ### THIS BREAKS ### //
                        }
                    }
                }
                break;
        }
    }
}

Model # 1 - Dieses Model befindet sich in einer Datenbank auf unserem Dev Server . Model # 1 http://content.screencast.com/users/Keith.Barrows/folders/Jing/media/bdb2b000-6e60-4af0 -a7a1-2bb6b05d8bc1/Model1.png

Modell 2 - Dieses Modell befindet sich in einer Datenbank auf unserem Prod Server und wird täglich durch automatische Feeds aktualisiert. alt text http://content.screencast.com/users/Keith.Barrows/folders/Jing/media/4260259f-bce6-43d5-9d2a-017bd9a980d4/Model2.png

Hinweis - Die rot eingekreisten Elemente in Modell 1 sind die Felder, die ich verwende, um Modell 2 zuzuordnen. Bitte ignorieren Sie die roten Kreise in Modell 2: das ist von einer anderen Frage, die ich hatte und die jetzt beantwortet wird.

Hinweis: Ich muss noch einen isDeleted-Check einfügen, damit ich ihn aus DB1 löschen kann, wenn er aus dem Inventar unseres Kunden gelöscht wurde.

Alles, was ich mit diesem speziellen Code tun möchte, ist, eine Firma in DB1 mit einem Client in DB2 zu verbinden, ihre Produktliste von DB2 abzurufen und sie in DB1 einzufügen, falls sie nicht bereits vorhanden ist. Das erste Mal sollte eine vollständige Bestandsaufnahme erfolgen. Jedes Mal, wenn es dort ausgeführt wird, sollte nichts passieren, es sei denn, über Nacht wurde neues Inventar in den Feed aufgenommen.

Also die große Frage - wie löse ich den Transaktionsfehler, den ich erhalte? Muss ich meinen Kontext jedes Mal durch die Schleifen ablegen und neu erstellen (ist für mich nicht sinnvoll)?

528
Keith Barrows

Nach langem Haarausfall entdeckte ich, dass die foreach-Schleifen die Schuldigen waren. Was passiert, ist EF aufzurufen, es aber in einen IList<T> dieses Zieltyps zurückzugeben und dann den IList<T> zu wiederholen.

Beispiel:

IList<Client> clientList = from a in _dbFeed.Client.Include("Auto") select a;
foreach (RivWorks.Model.NegotiationAutos.Client client in clientList)
{
   var companyFeedDetailList = from a in _dbRiv.AutoNegotiationDetails where a.ClientID == client.ClientID select a;
    // ...
}
605
Keith Barrows

Wie Sie bereits festgestellt haben, können Sie nicht über eine foreach speichern, die noch über einen aktiven Reader aus der Datenbank zeichnet.

Das Aufrufen von ToList() oder ToArray() ist für kleine Datensätze in Ordnung, aber wenn Sie Tausende von Zeilen haben, benötigen Sie viel Speicherplatz.

Es ist besser, die Zeilen in Stücken zu laden.

public static class EntityFrameworkUtil
{
    public static IEnumerable<T> QueryInChunksOf<T>(this IQueryable<T> queryable, int chunkSize)
    {
        return queryable.QueryChunksOfSize(chunkSize).SelectMany(chunk => chunk);
    }

    public static IEnumerable<T[]> QueryChunksOfSize<T>(this IQueryable<T> queryable, int chunkSize)
    {
        int chunkNumber = 0;
        while (true)
        {
            var query = (chunkNumber == 0)
                ? queryable 
                : queryable.Skip(chunkNumber * chunkSize);
            var chunk = query.Take(chunkSize).ToArray();
            if (chunk.Length == 0)
                yield break;
            yield return chunk;
            chunkNumber++;
        }
    }
}

In Anbetracht der obigen Erweiterungsmethoden können Sie Ihre Abfrage folgendermaßen schreiben:

foreach (var client in clientList.OrderBy(c => c.Id).QueryInChunksOf(100))
{
    // do stuff
    context.SaveChanges();
}

Das abfragbare Objekt, für das Sie diese Methode aufrufen, muss bestellt werden. Dies liegt daran, dass Entity Framework IQueryable<T>.Skip(int) nur für geordnete Abfragen unterstützt. Dies ist sinnvoll, wenn Sie der Meinung sind, dass mehrere Abfragen für unterschiedliche Bereiche erfordern, dass die Reihenfolge stabil ist. Wenn die Reihenfolge für Sie nicht wichtig ist, bestellen Sie einfach nach Primärschlüssel, da dies wahrscheinlich einen gruppierten Index enthält.

Diese Version fragt die Datenbank in Stapeln von 100 ab. Beachten Sie, dass SaveChanges() für jede Entität aufgerufen wird.

Wenn Sie Ihren Durchsatz erheblich verbessern möchten, sollten Sie SaveChanges() seltener anrufen. Verwenden Sie stattdessen Code wie folgt:

foreach (var chunk in clientList.OrderBy(c => c.Id).QueryChunksOfSize(100))
{
    foreach (var client in chunk)
    {
        // do stuff
    }
    context.SaveChanges();
}

Dies führt zu 100-mal weniger Datenbankaktualisierungsaufrufen. Natürlich dauert jeder dieser Anrufe länger, aber Sie kommen am Ende trotzdem weit vorne. Ihre Laufleistung kann variieren, aber für mich waren dies Welten schneller.

Und es kommt um die Ausnahme herum, die Sie gesehen haben.

EDITIch habe diese Frage nach dem Ausführen von SQL Profiler erneut aufgegriffen und ein paar Dinge aktualisiert, um die Leistung zu verbessern. Für jeden, der interessiert ist, hier ein Beispiel-SQL, das zeigt, was von der Datenbank erstellt wird.

Die erste Schleife muss nichts überspringen, daher ist es einfacher.

SELECT TOP (100)                     -- the chunk size 
[Extent1].[Id] AS [Id], 
[Extent1].[Name] AS [Name], 
FROM [dbo].[Clients] AS [Extent1]
ORDER BY [Extent1].[Id] ASC

Nachfolgende Aufrufe müssen vorherige Ergebnisblöcke überspringen. Daher wird die Verwendung von row_number eingeführt:

SELECT TOP (100)                     -- the chunk size
[Extent1].[Id] AS [Id], 
[Extent1].[Name] AS [Name], 
FROM (
    SELECT [Extent1].[Id] AS [Id], [Extent1].[Name] AS [Name], row_number()
    OVER (ORDER BY [Extent1].[Id] ASC) AS [row_number]
    FROM [dbo].[Clients] AS [Extent1]
) AS [Extent1]
WHERE [Extent1].[row_number] > 100   -- the number of rows to skip
ORDER BY [Extent1].[Id] ASC
246
Drew Noakes

Wir haben jetzt eine offizielle Antwort auf den auf Connect geöffneten Fehler gepostet. Wir empfehlen folgende Problemumgehungen:

Dieser Fehler ist darauf zurückzuführen, dass Entity Framework während des Aufrufs von SaveChanges () eine implizite Transaktion erstellt. Der beste Weg, den Fehler zu umgehen, besteht darin, ein anderes Muster zu verwenden (d. H. Nicht während des Lesens speichern) oder explizit eine Transaktion zu deklarieren. Hier sind drei mögliche Lösungen:

// 1: Save after iteration (recommended approach in most cases)
using (var context = new MyContext())
{
    foreach (var person in context.People)
    {
        // Change to person
    }
    context.SaveChanges();
}

// 2: Declare an explicit transaction
using (var transaction = new TransactionScope())
{
    using (var context = new MyContext())
    {
        foreach (var person in context.People)
        {
            // Change to person
            context.SaveChanges();
        }
    }
    transaction.Complete();
}

// 3: Read rows ahead (Dangerous!)
using (var context = new MyContext())
{
    var people = context.People.ToList(); // Note that this forces the database
                                          // to evaluate the query immediately
                                          // and could be very bad for large tables.

    foreach (var person in people)
    {
        // Change to person
        context.SaveChanges();
    }
} 
117

Fügen Sie einfach context.SaveChanges() nach dem Ende Ihrer foreach (Schleife) ein.

14
Majid

Tatsächlich können Sie Änderungen nicht in einer foreach-Schleife in C # mit Entity Framework speichern. 

Die context.SaveChanges()-Methode verhält sich wie ein Commit in einem regulären Datenbanksystem (RDMS). 

Nehmen Sie einfach alle Änderungen vor (die von Entity Framework zwischengespeichert werden), und speichern Sie dann alle gleichzeitig, indem Sie SaveChanges() nach der Schleife (außerhalb der Schleife) aufrufen, wie ein Befehl zum Eingeben der Datenbank.

Dies funktioniert, wenn Sie alle Änderungen gleichzeitig speichern können.

8

Zu Ihrer Information: aus einem Buch und einigen Zeilen, die angepasst wurden, weil sie noch gültig sind:

Durch das Aufrufen der SaveChanges () - Methode wird eine Transaktion gestartet, die automatisch alle in der Datenbank gespeicherten Änderungen rückgängig macht, wenn vor der Iteration eine Ausnahme auftritt. Andernfalls wird die Transaktion festgeschrieben. Sie werden möglicherweise versucht sein, die Methode nach jeder Aktualisierung oder Löschung einer Entität anzuwenden und nicht nach der Iteration, insbesondere wenn Sie eine große Anzahl von Entitäten aktualisieren oder löschen.

Wenn Sie versuchen, SaveChanges () aufzurufen, bevor alle Daten verarbeitet wurden, entsteht eine "Neue Transaktion ist nicht zulässig, da in der Sitzung andere Threads ausgeführt werden". Die Ausnahme tritt auf, weil SQL Server das Starten einer neuen Transaktion in einer Verbindung mit geöffnetem SqlDataReader nicht zulässt, selbst wenn mehrere aktive Datensatzgruppen (MARS) durch die Verbindungszeichenfolge aktiviert sind (die standardmäßige Verbindungszeichenfolge von EF aktiviert MARS).

Manchmal ist es besser zu verstehen, warum etwas passiert ;-)

6

Verwenden Sie immer Ihre Auswahl als Liste

Z.B:

var tempGroupOfFiles = Entities.Submited_Files.Where(r => r.FileStatusID == 10 && r.EventID == EventId).ToList();

Führen Sie dann eine Schleife durch, während Sie die Änderungen speichern

 foreach (var item in tempGroupOfFiles)
             {
                 var itemToUpdate = item;
                 if (itemToUpdate != null)
                 {
                     itemToUpdate.FileStatusID = 8;
                     itemToUpdate.LastModifiedDate = DateTime.Now;
                 }
                 Entities.SaveChanges();

             }
4
mzonerz

Ich bekam das gleiche Problem, aber in einer anderen Situation. Ich hatte eine Liste mit Elementen in einem Listenfeld. Der Benutzer kann auf ein Element klicken und "Löschen" auswählen, aber ich verwende eine gespeicherte Prozedur, um das Element zu löschen, da beim Löschen des Elements viele Logik involviert ist. Wenn ich die gespeicherte Prozedur aufrufe, funktioniert das Löschen gut, aber alle zukünftigen Aufrufe von SaveChanges verursachen den Fehler. Meine Lösung bestand darin, das gespeicherte proc außerhalb von EF aufzurufen, und dies funktionierte einwandfrei. Wenn ich aus irgendeinem Grund die gespeicherte Prozedur mit der EF-Methode anrufe, bleibt etwas offen.

4
MikeKulls

Hier sind zwei weitere Optionen, mit denen Sie SaveChanges () in einer Schleife für jede Schleife aufrufen können.

Die erste Option ist die Verwendung eines DBContext-Objekts zum Generieren der Listenobjekte, die durchlaufen werden sollen, und dann ein zweites DBContext-Objekt zum Aufrufen von SaveChanges () erstellen. Hier ist ein Beispiel:

//Get your IQueryable list of objects from your main DBContext(db)    
IQueryable<Object> objects = db.Object.Where(whatever where clause you desire);

//Create a new DBContext outside of the foreach loop    
using (DBContext dbMod = new DBContext())
{   
    //Loop through the IQueryable       
    foreach (Object object in objects)
    {
        //Get the same object you are operating on in the foreach loop from the new DBContext(dbMod) using the objects id           
        Object objectMod = dbMod.Object.Find(object.id);

        //Make whatever changes you need on objectMod
        objectMod.RightNow = DateTime.Now;

        //Invoke SaveChanges() on the dbMod context         
        dbMod.SaveChanges()
    }
}

Die zweite Option besteht darin, eine Liste von Datenbankobjekten aus DBContext abzurufen, aber nur die IDs auszuwählen. Durchlaufen Sie dann die Liste der IDs (vermutlich ein int), und erhalten Sie das Objekt, das jedem int entspricht, und rufen Sie SaveChanges () auf diese Weise auf. Die Idee hinter dieser Methode ist das Sammeln einer großen Liste von Ganzzahlen. Sie ist viel effizienter als das Abrufen einer großen Liste von DB-Objekten und das Aufrufen von .ToList () für das gesamte Objekt. Hier ist ein Beispiel für diese Methode:

//Get the list of objects you want from your DBContext, and select just the Id's and create a list
List<int> Ids = db.Object.Where(enter where clause here)Select(m => m.Id).ToList();

var objects = Ids.Select(id => db.Objects.Find(id));

foreach (var object in objects)
{
    object.RightNow = DateTime.Now;
    db.SaveChanges()
}
3
jjspierx

Ich musste ein riesiges ResultSet lesen und einige Datensätze in der Tabelle aktualisieren ... Ich versuchte, Chunks zu verwenden, wie in Drew Noakes 's answer vorgeschlagen.

Leider habe ich nach 50000 Datensätzen OutofMemoryException . Die Antwort Entity Framework große Datenmenge, keine Speicherausnahme erklärt, dass 

EF erstellt eine zweite Kopie der Daten, die zur Änderungserkennung verwendet werden (damit Änderungen an der Datenbank beibehalten können). EF hält diesen zweiten Satz für die lebensdauer des kontexts und dessen dieses set laufen sie aus der Erinnerung.

Es wird empfohlen, den Kontext für jede Charge zu erneuern.

Ich habe also Minimal- und Maximum-Werte des Primärschlüssels abgerufen. Die Tabellen haben Primärschlüssel als inkrementelle Auto-Integer-Werte. Dann habe ich aus den Datenbankblöcken der Datensätze durch Öffnen des Kontexts für jeden Block abgerufen. Nach der Verarbeitung wird der Chunk-Kontext geschlossen und der Speicher freigegeben. Dadurch wird sichergestellt, dass die Speichernutzung nicht wächst.

Hier ist ein Ausschnitt aus meinem Code: 

  public void ProcessContextByChunks ()
  {
        var tableName = "MyTable";
         var startTime = DateTime.Now;
        int i = 0;
         var minMaxIds = GetMinMaxIds();
        for (int fromKeyID= minMaxIds.From; fromKeyID <= minMaxIds.To; fromKeyID = fromKeyID+_chunkSize)
        {
            try
            {
                using (var context = InitContext())
                {   
                    var chunk = GetMyTableQuery(context).Where(r => (r.KeyID >= fromKeyID) && (r.KeyID < fromKeyID+ _chunkSize));
                    try
                    {
                        foreach (var row in chunk)
                        {
                            foundCount = UpdateRowIfNeeded(++i, row);
                        }
                        context.SaveChanges();
                    }
                    catch (Exception exc)
                    {
                        LogChunkException(i, exc);
                    }
                }
            }
            catch (Exception exc)
            {
                LogChunkException(i, exc);
            }
        }
        LogSummaryLine(tableName, i, foundCount, startTime);
    }

    private FromToRange<int> GetminMaxIds()
    {
        var minMaxIds = new FromToRange<int>();
        using (var context = InitContext())
        {
            var allRows = GetMyTableQuery(context);
            minMaxIds.From = allRows.Min(n => (int?)n.KeyID ?? 0);  
            minMaxIds.To = allRows.Max(n => (int?)n.KeyID ?? 0);
        }
        return minMaxIds;
    }

    private IQueryable<MyTable> GetMyTableQuery(MyEFContext context)
    {
        return context.MyTable;
    }

    private  MyEFContext InitContext()
    {
        var context = new MyEFContext();
        context.Database.Connection.ConnectionString = _connectionString;
        //context.Database.Log = SqlLog;
        return context;
    }

FromToRange ist eine einfache Struktur mit den Eigenschaften From und To.

2

In diesem Projekt hatte ich genau das gleiche Problem. Das Problem bestand nicht in der Variablen foreach oder .toList(), sondern in der von uns verwendeten AutoFac-Konfiguration. Dies führte zu einigen seltsamen Situationen, in denen der obige Fehler ausgegeben wurde, aber auch eine Menge von anderen äquivalenten Fehlern wurden geworfen.

Dies war unser Fix: Geändert:

container.RegisterType<DataContext>().As<DbContext>().InstancePerLifetimeScope();
container.RegisterType<DbFactory>().As<IDbFactory>().SingleInstance();
container.RegisterType<UnitOfWork>().As<IUnitOfWork>().InstancePerRequest();

Zu:

container.RegisterType<DataContext>().As<DbContext>().As<DbContext>();
container.RegisterType<DbFactory>().As<IDbFactory>().As<IDbFactory>().InstancePerLifetimeScope();
container.RegisterType<UnitOfWork>().As<IUnitOfWork>().As<IUnitOfWork>();//.InstancePerRequest();
2
VeldMuijz

Ich stand auch vor demselben Problem.

Hier ist die Ursache und Lösung.

http://blogs.msdn.com/b/cbiyikoglu/archive/2006/11/21/mars-transactions-and-sql-error-3997-3988-or-3983.aspx

Stellen Sie sicher, dass Sie vor dem Auslösen von Datenbearbeitungsbefehlen wie Einfügungen und Aktualisierungen alle vorherigen aktiven SQL-Reader geschlossen haben.

Die häufigsten Fehler sind Funktionen, die Daten aus db lesen und Werte zurückgeben. Für Funktionen wie isRecordExist.

In diesem Fall kehren wir sofort von der Funktion zurück, wenn wir den Datensatz gefunden haben, und vergessen, den Leser zu schließen.

1
Vinod T. Patil

In meinem Fall trat das Problem auf, als ich Stored Procedure über EF aufrief und SaveChanges später diese Ausnahme auslöst. Das Problem bestand im Aufruf der Prozedur, der Enumerator wurde nicht gelöscht. Ich habe den Code folgendermaßen korrigiert:

public bool IsUserInRole(string username, string roleName, DataContext context)
{          
   var result = context.aspnet_UsersInRoles_IsUserInRoleEF("/", username, roleName);

   //using here solved the issue
   using (var en = result.GetEnumerator()) 
   {
     if (!en.MoveNext())
       throw new Exception("emty result of aspnet_UsersInRoles_IsUserInRoleEF");
     int? resultData = en.Current;

     return resultData == 1;//1 = success, see T-SQL for return codes
   }
}
1
Tomas Kubes

Ich bin viel zu spät zur Party gekommen, aber heute sah ich mich mit dem gleichen Fehler konfrontiert und die Lösung war einfach. Mein Szenario ähnelte dem angegebenen Code, den ich in geschachtelten for-each-Schleifen durchführte.

Das Problem ist, dass eine Single-DB-Transaktion etwas länger dauert als die for-each-Schleife. Sobald die vorherige Transaktion nicht abgeschlossen ist, löst die neue Traktion eine Ausnahme aus, sodass die Lösung ein neues Objekt in der for-each-Schleife erstellt wo Sie eine DB-Transaktion durchführen.

Für die oben genannten Szenarien sieht die Lösung folgendermaßen aus:

foreach (RivWorks.Model.Negotiation.AutoNegotiationDetails companyFeedDetail in companyFeedDetailList)
                {
private RivWorks.Model.Negotiation.RIV_Entities _dbRiv = RivWorks.Model.Stores.RivEntities(AppSettings.RivWorkEntities_connString);
                    if (companyFeedDetail.FeedSourceTable.ToUpper() == "AUTO")
                    {
                        var company = (from a in _dbRiv.Company.Include("Product") where a.CompanyId == companyFeedDetail.CompanyId select a).First();
                        foreach (RivWorks.Model.NegotiationAutos.Auto sourceProduct in client.Auto)
                        {
                            foreach (RivWorks.Model.Negotiation.Product targetProduct in company.Product)
                            {
                                if (targetProduct.alternateProductID == sourceProduct.AutoID)
                                {
                                    found = true;
                                    break;
                                }
                            }
                            if (!found)
                            {
                                var newProduct = new RivWorks.Model.Negotiation.Product();
                                newProduct.alternateProductID = sourceProduct.AutoID;
                                newProduct.isFromFeed = true;
                                newProduct.isDeleted = false;
                                newProduct.SKU = sourceProduct.StockNumber;
                                company.Product.Add(newProduct);
                            }
                        }
                        _dbRiv.SaveChanges();  // ### THIS BREAKS ### //
                    }
                }
0
Usman

Der folgende Code funktioniert für mich:

private pricecheckEntities _context = new pricecheckEntities();

...

private void resetpcheckedtoFalse()
{
    try
    {
        foreach (var product in _context.products)
        {
            product.pchecked = false;
            _context.products.Attach(product);
            _context.Entry(product).State = EntityState.Modified;
        }
        _context.SaveChanges();
    }
    catch (Exception extofException)
    {
        MessageBox.Show(extofException.ToString());

    }
    productsDataGrid.Items.Refresh();
}
0
user2918896

Erstellen Sie Ihre abfragbaren Listen in .ToList (), und es sollte einwandfrei funktionieren. 

0

Ich weiß, es ist eine alte Frage, aber heute bin ich mit diesem Fehler konfrontiert. 

ich habe festgestellt, dass dieser Fehler ausgelöst werden kann, wenn ein Auslöser einer Datenbanktabelle einen Fehler ausgibt.

zu Ihrer Information können Sie auch die Trigger Ihrer Tabellen überprüfen, wenn Sie diesen Fehler erhalten.

0
nadir

Wenn Sie diesen Fehler aufgrund von foreach erhalten und wirklich eine Entität zuerst in der Schleife speichern und die generierte Identität in der Schleife weiter verwenden müssen, wie in meinem Fall, ist die einfachste Lösung die Verwendung eines anderen DBContext zum Einfügen einer Entität, die Id und use zurückgibt Diese Id im äußeren Kontext

Zum Beispiel 

    using (var context = new DatabaseContext())
    {
        ...
        using (var context1 = new DatabaseContext())
        {
            ...
               context1.SaveChanges();
        }                         
        //get id of inserted object from context1 and use is.   
      context.SaveChanges();
   }
0
Hemant Sakta

Ich bin etwas spät dran, aber ich hatte auch diesen Fehler. Ich löste das Problem, indem ich überprüfte, was wo die Werte waren, die aktualisiert wurden.

Ich fand heraus, dass meine Abfrage falsch war und dass über 250 Änderungen anstanden. Also habe ich meine Abfrage korrigiert und jetzt funktioniert es korrekt.

Also in meiner Situation: Überprüfen Sie die Abfrage auf Fehler, indem Sie das Ergebnis der Abfrage debuggen. Danach korrigieren Sie die Abfrage.

Ich hoffe, dies hilft bei der Lösung zukünftiger Probleme.

0
Max