2009-03-31 5 views
22

Ich habe eine vollständige Trennung von meiner Entity Framework Objekte und meine POCO Objekte, ich sie gerade übersetzen hin und her ...Wie kann ich ein Entity Framework-Objekt anfügen, das nicht aus der Datenbank stammt?

dh:

// poco 
public class Author 
{ 
    public Guid Id { get; set; } 
    public string UserName { get; set; } 
} 

und dann habe ich ein EF-Objekt „Autoren“ mit den gleichen Eigenschaften ..

so habe ich mein Business-Objekt

var author = new Author { UserName="foo", Id="Guid thats in the db" }; 

und ich möchte dieses Objekt speichern, damit ich den follo tun Flügel:

var dbAuthor = new dbAuthor { Id=author.Id, UserName=author.UserName }; 
entities.Attach(dbAuthor); 
entities.SaveChanges(); 

aber das gibt mir die folgende Fehlermeldung:

An object with a null EntityKey value cannot be attached to an object context.

EDIT: Es ist wie ich ("Autoren", dbAuthor) verwenden müssen entities.AttachTo aussieht; ohne EntityKey anzuhängen, aber dann habe ich fest codierte magische Zeichenfolgen, die brechen werden, wenn ich meine Entity-Set-Namen überhaupt ändere und keine Compile-Time-Überprüfung habe ... Gibt es einen Weg, den ich anhängen kann, der die Kompilierzeit überprüft ?

Ich hoffe, würde ich in der Lage sein würde, dies zu tun, als hart codierte Strings Kompilierung Validierung töten würde saugen =)

+0

Hast du dir das Edit meiner Antwort angesehen, es wird y erlauben ou, um es ohne magische Zeichenfolgen oder AttachTo zu tun, da die Methoden vom edmx-Modell vom Designer erzeugt werden und beibehalten werden. –

+0

Ja, ich füge es nicht hinzu, ich aktualisiere es, daher muss ich es anhängen und Änderungen speichern – sontek

+0

Ich glaube immer noch, dass Ihr Modell ein Problem mit der Id-Eigenschaft des Autorenobjekts hat, das nicht als EntityKey festgelegt ist verdoppeln, sollten Sie die XML überprüfen generiert und stellen Sie sicher, dass es in einem Schlüsselelement verschachtelt ist und sicherstellen, dass die Id-Eigenschaft das Attribut EdmScalarPropertyAttribute (EntityKeyProperty = true) –

Antwort

13

Haben Sie AttachTo und Angabe des Entitätssatz versucht, mit? ..

entities.AttachTo("Authors", dbAuthor); 

wo "Authors" wäre Ihr tatsächlicher Entity-Set-Name.

Edit:
Ja gibt es einen besseren Weg (gut sollte es sein). Der Designer sollte "Add" methods auf die Object für Sie generiert haben, die oben .. auf den Aufruf übersetzen, so sollten Sie tun können:

entities.AddToAuthors(dbAuthor); 

die buchstäblich sein sollte:

public void AddToAuthors(Authors authors) 
{ 
    base.AddObject("Authors", authors); 
} 

in der definiert whateverobjectcontext.designer.cs-Datei.

+4

Dies scheint zu funktionieren, aber dann habe ich "magische Zeichenfolgen" überall, und wenn ich die umbenennen Entity Set all mein Code wird brechen. Gibt es einen besseren Weg, dies zu tun? – sontek

+0

@Ashkan Ihre Bearbeitung macht die Antwort falsch, die automatisch generierte 'AddToAuthors' verwendet nicht 'EntitySet.Name', und Ihre Bearbeitung behauptet, dass es tut, also habe ich es rückgängig gemacht. Das Prinzip, das hinter deiner Bearbeitung steht, sieht gut aus, und das ist es, was in einer anderen Antwort verwendet wird, die ich aufgewertet habe, und ich ermutige dich, dasselbe zu tun. – hvd

15

Das gerade jetzt sehen. Wenn Sie auf die Object Attach() wollen, überzeugen dh das Entity Framework, die ein Unternehmen bereits in der Datenbank vorhanden ist, und Sie wollen also mit magischen Saiten können

ctx.AttachTo("EntitySet", entity); 

Sie versuchen, zwei Möglichkeiten, basierend auf Erweiterungsmethoden vermeiden Beide machen das Leben definitiv erträglicher.

Die erste Option können Sie schreiben:

ctx.AttachToDefault(entity); 

und wird hier abgedeckt: Tip 13 - How to attach an entity the easy way

Die zweite Option, die Sie schreiben können:

ctx.EntitySet.Attach(entity); 

und wird hier abgedeckt: Tip 16 - How to mimic .NET 4.0's ObjectSet today

Wie Sie sehen können, sind beide wirklich einfach zu verwenden und Strings überhaupt zu vermeiden.

this helps

Alex

-2

Für mich

Context.Authors.AddObject(new Author()) 

funktioniert perfekt. Fragst du dich, ob mir etwas fehlt? Oder ist es nicht der richtige Weg?

+4

Dies wird für neue Objekte verwendet, nicht für vorhandene. – ReinierDG

5

die Sie interessieren, wenn Sie die Zeichenfolge mit dem Namen EntitySet

entities.AttachTo(entities.CreateObjectSet<T>().EntitySet.Name, entity); 
+0

'entities.Authors.Attach (dbAuthor);' ist schöner. – ReinierDG

+0

Ich habe meinen Code in einer generischen Methode verwendet, bei der ich jede Art von Entity gat ... – sebagomez

0

Können Sie folgende versuchen schreiben wollen

entities.AddToAuthors(dbAuthor); 
+1

Dies ist wirklich ein Kommentar, keine Antwort auf die Frage. Du kannst deine eigenen Beiträge immer kommentieren, und sobald du genügend [Reputation] hast (http://stackoverflow.com/faq#reputation) kannst du [jeden Beitrag kommentieren] (http://stackoverflow.com/) Privilegien/Kommentar). –

+1

@BryanCrosby Ich stimme nicht zu. Ich glaube, das ist eine Antwort, kein Kommentar. – mayu

4

eine Alternative dazu ist, wie insbesondere Folgendes, wenn Sie don Ich weiß nicht, auf welcher Stelle du operierst:

string className = entityObject.GetType().Name; 
var container = _DbContext.MetadataWorkspace.GetEntityContainer(_DbContext.DefaultContainerName, DataSpace.CSpace); 
string setName = (from meta in container.BaseEntitySets 
        where meta.ElementType.Name == className 
        select meta.Name).First(); 
_DbContext.AttachTo(setName, entityObject); 
+0

Vielen Dank dafür, keine Ahnung, wie Sie das herausgefunden haben, aber ich stolperte darüber, als ich nach einer Möglichkeit suchte, genau das zu tun. Ich benutze das Code First Stored Procedures-Projekt von https://www.codeproject.com/articles/179481/code-first-stored-procedures und war nicht glücklich, dass die Elemente nicht zum DbContext-Tracking hinzugefügt wurden. Mit diesem Code konnte ich sie hinzufügen. Es ist nicht perfekt, weil sie ohne den Proxy-Code zu Lazy Load-Eigenschaften hinzugefügt werden, aber es funktioniert gut genug für mich. – Brad

Verwandte Themen