2009-07-15 23 views
1

Ich verwende LINQ2SQL und ich habe eine TabelleLINQ to SQL DuplicateKeyException Problem

CustmerID, CustomerCode, Kundenname

CustmerID ist Primery Key (und Identität = yes) und CustomerCode Kunden mit drei Spalten hat gerade angerufen wird UniqueKey .

Wenn ich diese Tabelle mithilfe von LINQ to SQL mit doppeltem Kundencode aktualisiere, erwarte ich, dass DuplicateKeyException angezeigt wird, aber es wird in den allgemeinen Ausnahmeblock statt in den DuplicateKeyException-Block aufgenommen. Irgendwelche Ideen?

Dies ist der Code

public void Update (Kunde Kd) { mit (LINQDemoDataContext db = new LINQDemoDataContext()) { Kunden entity = CustomerMapper.ToEntity (neue Kunden,(), cust);

  try 
      { 
       db.Customers.Attach(entity, true); 
       db.SubmitChanges(); 
      } 

      //Concurrency Exception 
      catch (ChangeConflictException) 
      {        
       throw new ChangeConflictException("A concurrency error occurred!"); 
      } 

      //duplicate record 
      catch (DuplicateKeyException) 
      { 
       throw new DuplicateKeyException(entity.CustmerCode); 
      } 

      //everything else 
      catch (Exception ex) 
      { 
       throw ex; 
      } 
     } 
    } 

Ich verwende VisualWebDeveloperExpress 2008 und SQL Express 2005

Dank & Grüße, Supremestar

+2

Wenn ich Exceptions wie diese ausspreche, würde ich die ursprüngliche Ausnahme als 'InnerException' (verwenden Sie einen anderen Konstruktor) verwenden. Anstatt "ex" zu werfen, verwenden Sie einfach "throw;". –

+0

Oder, einfach nicht die letzte Ausnahme abfangen, wenn Sie nicht damit umgehen. –

+0

Danke für den Tipp. Aber was ist mit der DuplicateKeyException? Was ist damit? catch (SqlException sqlExc) { foreach (SqlError Fehler in sqlExc.Errors) { if (error.Number == 2601) { throw new Exception ("kann der Kunde Datensatz nicht aktualisieren, CustomerCode muss eindeutig sein "); } sonst { werfen; } } – Supremestar

Antwort

2

Wenn der Speicher dient, und ich kann hier falsch sein, die DuplicateKeyException nur Feuer für den Primärschlüssel des Tisches.

+0

Sind Sie sicher Stephen? Danke für deine Antwort. – Supremestar

+0

Über 70% sicher. Wenn Sie das try/catch auskommentieren und es im Debug ausführen, können Sie genau herausfinden, welche Ausnahme geworfen wird, da die IDE es Ihnen sagen wird. –

0

Ich stieß auf das gleiche Problem, wo die doppelten Schlüsselobjekte im Speicher gehalten wurden, obwohl sie nicht in die Datenbank eingefügt wurden. Ich kam mit der folgenden Aufarbeiten um:

MyDataContext _myDataContext = new MyDataContext(ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString); 

    public void AddObject(object myObject) 
    { 
     try 
     { 
      _myDataContext.Objects.InsertOnSubmit(myObject); 
      _myDataContext.SubmitChanges(); 
     } 
     catch (System.Data.Linq.DuplicateKeyException ex) 
     { 
      _myDataContext = new MyDataContext(ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString); 
      throw ex; 

Sie können dann fangen und verarbeiten (oder ignorieren) die geworfen DuplicateKeyException in dem Anrufer.

Eine andere Work around (wenn auch ineffizient und Speicher-hogging) besteht darin, einen neuen Datenkontext innerhalb der AddObject-Methode zu erstellen, anstatt den freigegebenen Datenkontext als Klassenmember zu verwenden.

0

Ich hatte das Problem beim Hinzufügen einer Entität, die ich von einem anderen DataContext erhalten habe.
(I verpflichtet, das FooDb-Eigentum eines BarDb-Entity zum SelectedValue von einem Dropdownlist, die eine Tabelle aus einer kurzlebigen Datacontext als Datasource hatte)
die am Linq2Sql internen Werfen sie einen Blick Attach (juristische Person):

private void attach_FooDb(FooDb entity){ 
    this.SendPropertyChanging(); 
    entity.BarDb = this; 
} 

und die BarDb Eigenschaftsset:

set{ 
    BarDb previousValue = this._BarDb.Entity; 
    if (((previousValue != value) || (this._BarDb.HasLoadedOrAssignedValue == false))){ 
     this.SendPropertyChanging(); 
     if ((previousValue != null)){ 
      this._BarDb.Entity = null; 
      previousValue.FooDb.Remove(this); 
     } 

     this._BarDb.Entity = value; 

     if ((value != null)){ 
      value.FooDb.Add(this); 
      this._FK_Bar = value.ID; 
     }else{ 
      this._FK_Bar = default(System.Guid); 
     } 
     this.SendPropertyChanged("BarDb"); 
    } 
} 

Also, wenn auf einen FooDb Befestigung, wird die entsprechende Datacontext des BarDb Entity erkennt als neu erstellt und hinzugefügt, auch wenn es bereits in der Datenbank existiert.

Sie können es lösen:

  • nur eine einzige Datacontext mit oder
  • ein BarDb_safe Eigentum in der Vorlage Datacontext zu schaffen, die zuerst die „gleich“ Einheit aus der Datenbank anfordert, gilt alle Eigenschaften und fügt es dann auf die übliche Weise an.