Asp.net mvc 如何创建与实体框架的外键关系?

Asp.net mvc 如何创建与实体框架的外键关系?,asp.net-mvc,entity-framework,foreign-key-relationship,Asp.net Mvc,Entity Framework,Foreign Key Relationship,我想在数据库中的一个表上创建一个新行,该表有两个外键关系,但我还不能确定需要执行的顺序和调用。这就是我到目前为止所做的: 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(); using (va

我想在数据库中的一个表上创建一个新行,该表有两个外键关系,但我还不能确定需要执行的顺序和调用。这就是我到目前为止所做的:

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();
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();
}
代码在第二行失败,表示:

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();
}
在以下情况下,“附加”不是有效的操作: 与此关联的源对象 相关端在添加、删除、, 或分离状态。加载的对象 使用NoTracking合并选项可以 总是超然的

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();
}
有什么想法吗?

(谢谢约翰的语法修正)

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();
}
所以我想出来了。这就是你必须做的:

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();
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();
}

我希望这能帮助人们。

为什么不使用实体引用?您的方法将导致额外的
SELECT
语句

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();
}
更好的方法是使用
CustomerReference
类和
EntityKey

order.CustomerReference = new System.Data.Objects.DataClasses.EntityReference<Customers>();
order.CustomerReference.EntityKey = new EntityKey("ModelsEntities.Customers", "Id", custId);
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();
}
order.CustomerReference=new System.Data.Objects.DataClasses.EntityReference();
order.CustomerReference.EntityKey=新的EntityKey(“ModelsEntities.Customers”,“Id”,custId);

更新示例代码如下:

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();
}

我不介意使用您的解决方案,但我希望使用强类型数据库列名,以便在关系无效时获得编译时错误。我同意kirkmcpherson的观点,他的方法避免了额外的选择。我猜您看重可维护代码而不是性能。您仍然可以使用他的方式,但是可以使用反射来生成字符串,而不是硬编码字符串,方法是获取上面示例中ModelSenties和Customers的类名。这样一来,您就可以少选择一次,并且会出现严重的键入/编译时错误。反射增加的开销在我看来应该不是问题。好的,您可以使用反射生成实体集名称,但不能生成键名称(即,可以使用强类型生成“ModelsEntities.Customers”)。是否有一种使用反射生成“Id”的方法?