2009-03-31 12 views
22

tengo una separación completa de mis objetos de Entity Framework y mis objetos POCO, yo sólo traduzco un lado a otro ...¿Cómo puedo adjuntar un objeto de Entity Framework que no es de la base de datos?

es decir:

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

y luego tengo un objeto EF "Autores" con las mismas propiedades ..

por lo que tengo a mi objeto de negocio

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

y quiero guardar este objeto así hago el Follo ala:

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

pero esto me da el siguiente error:

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

EDIT: Parece que tengo que usar entities.AttachTo ("Autores", dbAuthor); para adjuntar sin una EntityKey, pero luego tengo cadenas mágicas codificadas, que se romperán si cambio los nombres de mis conjuntos de entidades y no tendré tiempo de compilación comprobando ... ¿Hay alguna manera de adjuntar que mantenga el tiempo de compilación? ?

Yo esperaría que fuera capaz de hacer esto, como cadenas codificadas duro matar a la validación en tiempo de compilación apestaría =)

+0

¿Usted miró la edición de mi respuesta? O para hacerlo sin cadenas mágicas o AttachTo ya que los métodos son generados y mantenidos por el modelo de edmx. –

+0

Sí, no lo estoy agregando, lo estoy actualizando, así que tengo que adjuntarme a él y guardar los cambios – sontek

+0

. Sigo creyendo que su modelo tiene un problema con la propiedad Id en el objeto Autores que no se configura como EntityKey , se debe revisar el XML generado y asegúrese de que está anidado en un elemento clave y asegúrese de que la propiedad Id tiene el atributo EdmScalarPropertyAttribute (EntityKeyProperty = true) –

Respuesta

13

¿Ha intentado utilizar AttachTo y especificando el conjunto de entidades? ..

entities.AttachTo("Authors", dbAuthor); 

donde "Authors" sería el nombre real de su conjunto de entidades.

Editar:
Sí, hay una mejor manera (bien debería haber). El diseñador debe haber generado "Add" methods a la ObjectContext para usted que se traducen a la llamada anterior .. Por lo que debe ser capaz de hacer:

entities.AddToAuthors(dbAuthor); 

que debería ser, literalmente:

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

definido en el archivo whateverobjectcontext.designer.cs.

+4

Esto parece funcionar, pero luego tengo "cadenas mágicas" en todas partes, y si cambio el nombre del entidad establece que todo mi código se romperá. ¿Hay una mejor manera de hacer esto? – sontek

+0

@Ashkan Su edición hace que la respuesta sea incorrecta, el 'generado automáticamente 'AddToAuthors' no utiliza' EntitySet.Name', y su edición dice que sí, así que lo he revertido. El principio detrás de tu edición me parece bien, y eso es lo que se usa en otra respuesta, que he votado como un voto ascendente, y te animo a que hagas lo mismo. – hvd

15

Solo estoy viendo esto ahora. Si desea adjuntar() a la ObjectContext, es decir, convencer al marco de la entidad que existe una entidad en la base de datos ya, y se quiere evitar el uso de cadenas mágicas, es decir

ctx.AttachTo("EntitySet", entity); 

Puede probar dos posibilidades sobre la base de los métodos de extensión , los cuales definitivamente hacen la vida más llevadera.

La primera opción le permite escribir:

ctx.AttachToDefault(entity); 

y está cubierto aquí: Tip 13 - How to attach an entity the easy way

La segunda opción le permite escribir:

ctx.EntitySet.Attach(entity); 

y se cubre aquí: Tip 16 - How to mimic .NET 4.0's ObjectSet today

Como puede ver, ambos son realmente fácil de usar y evitar cadenas por completo.

Esperanza esto ayuda

Alex

-2

Para mí,

Context.Authors.AddObject(new Author()) 

funciona perfectamente. ¿Me estoy preguntando si me estoy perdiendo algo? O no es el camino correcto?

+4

Esto se usa para objetos nuevos, no para los existentes. – ReinierDG

5

Prueba esto si no desea escribir la cadena con el nombre EntitySet

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

'entities.Authors.Attach (dbAuthor);' es más agradable. – ReinierDG

+0

Utilicé mi código en un método genérico donde puedo reunir cualquier tipo de entidad ... – sebagomez

0

Se puede tratar después

entities.AddToAuthors(dbAuthor); 
+1

Esto es realmente un comentario, no una respuesta a la pregunta. Siempre puede comentar sus propias publicaciones, y una vez que tenga suficiente [reputación] (http://stackoverflow.com/faq#reputation) podrá [comentar cualquier publicación] (http://stackoverflow.com/ privilegios/comentario). –

+1

@BryanCrosby No estoy de acuerdo. Creo que esta es una respuesta, no un comentario. – mayu

4

una alternativa a esto es la siguiente, en particular si no No sé en qué entidad va a operar:

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

Gracias por esto, no tengo idea de cómo lo descubriste, pero me topé con él cuando buscaba una manera de hacer exactamente esto. Estoy usando el proyecto Code First Stored Procedures de https://www.codeproject.com/articles/179481/code-first-stored-procedures y no estaba contento de que los elementos no se hayan agregado al seguimiento de DbContext. Usando este código, pude agregarlos. No es perfecto porque se agregan sin el código proxy a las propiedades de carga lenta, pero funciona lo suficientemente bien para mí. – Brad

Cuestiones relacionadas