2008-10-13 23 views
5

Quiero crear una nueva fila en mi base de datos en una tabla que tenga un par de relaciones de claves foráneas y no he podido conocer qué orden y qué llamadas deben realizarse. Esto es lo que tengo hasta ahora:¿Cómo crear relaciones de claves foráneas con Entity Framework?

db.Models.Order order = DB.Models.Order.CreateOrder(apple); 
order.CustomerReference.Attach((from c in db.Customer where c.Id == custId select c).First()); 
db.SaveChanges(); 

El código está fallando en la segunda línea allí, diciendo:

Acople no es una operación válida cuando el objeto de origen asociado con este fin relacionado está en un estado agregado, eliminado, o separado. Los objetos cargados utilizando la opción de fusión NoTracking son siempre separados.

¿Alguna idea?

Respuesta

8

(Gracias John por las correcciones gramaticales)

Así que lo he descubierto. Esto es lo que tiene que hacer:

db.Models.Order order = DB.Models.Order.CreateOrder(apple); 
order.Customer = (from c in db.Customer where c.Id == custId select c).First(); 
db.SaveChanges(); 

Espero que ayude a las personas.

6

¿Por qué no utilizar referencias de entidad? Su método causará una declaración adicional SELECT.

Una forma mucho más agradable es utilizar la clase CustomerReference y EntityKey.

order.CustomerReference = new System.Data.Objects.DataClasses.EntityReference<Customers>(); 
order.CustomerReference.EntityKey = new EntityKey("ModelsEntities.Customers", "Id", custId); 
+1

No me importaría usar su solución, pero me gustaría utilizar los nombres de columna de base de datos de tipo fuerte para que pueda obtener en tiempo de compilación si la relación es inválida – Jared

+0

Estoy de acuerdo con kirkmcpherson, su forma de evitar el SELECT extra. Supongo que valoras el código que se puede mantener sobre el rendimiento. Todavía puede usar su camino, pero en lugar de cadenas codificadas, puede usar la reflexión para generar las cadenas obteniendo los nombres de clase para ModelsEntities y Customers en el ejemplo anterior. De esta forma obtienes tanto uno menos SELECCIONAR, y fuertes errores de tipeo/tiempo de compilación. La sobrecarga adicional de la reflexión no debería ser un problema de la OMI. – jamiebarrow

+0

De acuerdo, puede usar el reflejo para generar el nombre del conjunto de entidades, pero no el nombre de clave (es decir, puede generar "ModelsEntities.Customers" usando el tipado fuerte). ¿Hay alguna manera de generar el "Id" usando la reflexión? – jamiebarrow

0

Para actualización aquí es un código de ejemplo:

using (var ctx = new DataModelEntities()) 
{ 

     var result = (from p in ctx.UserRole.Where(o => o.UserRoleId == userRole.UserRoleId) 
           select p).First(); 

     result.RolesReference.EntityKey = new EntityKey("DataModelEntities.Roles", 
             "RoleId", userRole.RoleId); 

     result.UserRoleDescription = userRole.UserRoleDescription;  
     ctx.SaveChanges(); 
} 
errores
Cuestiones relacionadas