我们如何在 ASP.NET Core & EF Core & C# 上将多个外键从一个模型添加到另一个模型
How can we add multiple foreign keys from one model to another on ASP.NET Core & EF Core & C#
假设我有一个 ApplicationUser : IdentityUser
模型 class,它具有身份关系,默认情况下它有一个字符串 ID,并且在用户注册时分配了角色。
ApplicationUsers
将有不同的角色,例如学生和图书馆。
图书馆会有图书清单,而学生会有订单清单。
现在我想创建一个名为 Orders
的另一个模型的列表,但是 Orders
模型 class 将有两个 UserId 作为来自 [=17] 的外键=].
ApplicationUser: IdentityUser
{
public string FirstName { get; set; }
public string LastName { get; set; }
public List<Libraries> Libraries { get; set; }
public List<Orders> Orders { get; set; }
}
由于 ApplicationUser
与 ASPNetRoles
相连,我想在 Orders
模型 class 上实现的是我想要不同的 StudentId
LibraryId
来自同一个 table 即 ApplicationUser
:
public class Orders
{
[Key]
public id OrderId {get; set;}
[ForeignKey("StudentId")]
public string StudentId { get; set; }
public ApplicationUser Student {get; set;}
[ForeignKey("LibraryId")]
public string LibraryId {get; set;}
public ApplicationUser Library {get; set;}
}
有什么办法可以做到这一点吗?这种情况的最佳解决方案是什么?我确实尝试 ICollection
并列出但仍然相同。任何关于此的建议都会很棒。
当我 运行 Add-Migrations
时,我得到这个错误:
System.InvalidOperationException: Unable to determine the relationship represented by navigation 'ApplicationUser.OrdersLists' of type 'ICollection'. Either manually configure the relationship, or ignore this property using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.
谢谢。
好的,你的模型看起来不太对...
在您的用户 class 中,您有一个订单集合和一个名为图书馆的 class 集合。然而,在您的订单 class 中,您有一个名为 Library 的 属性,但指向 ApplicationUser class?
EF 确实支持对同一个 class 进行多次引用,但您需要明确告诉它 FK 名称是什么。 EF 的默认约定是将 FK 名称基于导航 属性 的 类型 ,而不是导航 属性.
的名称
取以下内容:
public class Order
{
....
public int CreatedById { get; set; }
public virtual ApplicationUser CreatedBy { get; set; }
public int LastModifiedById { get; set; }
public virtual ApplicationUser LastModifiedBy { get; set; }
}
默认情况下,EF 希望使用“ApplicationUser_Id”或“ApplicationUserId”作为两个导航属性的 FK 名称,选择“ApplicationUser_Id”和“ApplicationUser_Id1" 如果留给它自己的设备与模式。在这种情况下,我们需要将其配置为使用我们所需的 FK 属性:
[ForeignKey("CreatedBy")]
public int CreatedById { get; set; }
public virtual ApplicationUser CreatedBy { get; set; }
[ForeignKey("LastModifiedBy")]
public int LastModifiedById { get; set; }
public virtual ApplicationUser LastModifiedBy { get; set; }
或者FK属性可以放在导航上属性:
public int CreatedById { get; set; }
[ForeignKey("CreatedById")]
public virtual ApplicationUser CreatedBy { get; set; }
public int LastModifiedById { get; set; }
[ForeignKey("LastModifiedById")]
public virtual ApplicationUser LastModifiedBy { get; set; }
ForeignKey
属性有点奇怪,因为它表示“我是...的 FK”(如果在 FK 属性 上,或者它表示“我的 FK 是 .. .." 如果在导航上 属性.
对于 EF Core,FK 属性 可以被 EF 忽略并被 EF 视为阴影 属性,建议避免实体中有两个真实来源。
[ForeignKey("CreatedById")]
public virtual ApplicationUser CreatedBy { get; set; }
[ForeignKey("LastModifiedById")]
public virtual ApplicationUser LastModifiedBy { get; set; }
如果您希望在关系的另一端引用 bi-directional,您可能需要将它们映射出来。例如,如果我想在我的 ApplicationUser class:
中使用“CreatedOrders”
public class ApplicationUser
{
// ...
public virtual ICollection<Order> CreatedOrders { get; set; } = new List<Order>();
}
现在通常最好告诉 EF 将其关联到什么,因为 Order 有两个对应用程序用户的引用。同样,这可以在关系的任何一方完成。所以在返回我们订单的情况下 class:
[ForeignKey("CreatedById"), InverseProperty("CreatedOrders")]
public virtual ApplicationUser CreatedBy { get; set; }
这告诉 EF 此记录上的 CreatedBy 是访问 CreatedOrders 的订单时要使用的 link。
回到你的例子,有点令人困惑为什么 ApplicationUser 会包含一个库的集合,而一个订单期望一个“库”是一个用户。
假设我有一个 ApplicationUser : IdentityUser
模型 class,它具有身份关系,默认情况下它有一个字符串 ID,并且在用户注册时分配了角色。
ApplicationUsers
将有不同的角色,例如学生和图书馆。
图书馆会有图书清单,而学生会有订单清单。
现在我想创建一个名为 Orders
的另一个模型的列表,但是 Orders
模型 class 将有两个 UserId 作为来自 [=17] 的外键=].
ApplicationUser: IdentityUser
{
public string FirstName { get; set; }
public string LastName { get; set; }
public List<Libraries> Libraries { get; set; }
public List<Orders> Orders { get; set; }
}
由于 ApplicationUser
与 ASPNetRoles
相连,我想在 Orders
模型 class 上实现的是我想要不同的 StudentId
LibraryId
来自同一个 table 即 ApplicationUser
:
public class Orders
{
[Key]
public id OrderId {get; set;}
[ForeignKey("StudentId")]
public string StudentId { get; set; }
public ApplicationUser Student {get; set;}
[ForeignKey("LibraryId")]
public string LibraryId {get; set;}
public ApplicationUser Library {get; set;}
}
有什么办法可以做到这一点吗?这种情况的最佳解决方案是什么?我确实尝试 ICollection
并列出但仍然相同。任何关于此的建议都会很棒。
当我 运行 Add-Migrations
时,我得到这个错误:
System.InvalidOperationException: Unable to determine the relationship represented by navigation 'ApplicationUser.OrdersLists' of type 'ICollection'. Either manually configure the relationship, or ignore this property using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.
谢谢。
好的,你的模型看起来不太对...
在您的用户 class 中,您有一个订单集合和一个名为图书馆的 class 集合。然而,在您的订单 class 中,您有一个名为 Library 的 属性,但指向 ApplicationUser class?
EF 确实支持对同一个 class 进行多次引用,但您需要明确告诉它 FK 名称是什么。 EF 的默认约定是将 FK 名称基于导航 属性 的 类型 ,而不是导航 属性.
的名称取以下内容:
public class Order
{
....
public int CreatedById { get; set; }
public virtual ApplicationUser CreatedBy { get; set; }
public int LastModifiedById { get; set; }
public virtual ApplicationUser LastModifiedBy { get; set; }
}
默认情况下,EF 希望使用“ApplicationUser_Id”或“ApplicationUserId”作为两个导航属性的 FK 名称,选择“ApplicationUser_Id”和“ApplicationUser_Id1" 如果留给它自己的设备与模式。在这种情况下,我们需要将其配置为使用我们所需的 FK 属性:
[ForeignKey("CreatedBy")]
public int CreatedById { get; set; }
public virtual ApplicationUser CreatedBy { get; set; }
[ForeignKey("LastModifiedBy")]
public int LastModifiedById { get; set; }
public virtual ApplicationUser LastModifiedBy { get; set; }
或者FK属性可以放在导航上属性:
public int CreatedById { get; set; }
[ForeignKey("CreatedById")]
public virtual ApplicationUser CreatedBy { get; set; }
public int LastModifiedById { get; set; }
[ForeignKey("LastModifiedById")]
public virtual ApplicationUser LastModifiedBy { get; set; }
ForeignKey
属性有点奇怪,因为它表示“我是...的 FK”(如果在 FK 属性 上,或者它表示“我的 FK 是 .. .." 如果在导航上 属性.
对于 EF Core,FK 属性 可以被 EF 忽略并被 EF 视为阴影 属性,建议避免实体中有两个真实来源。
[ForeignKey("CreatedById")]
public virtual ApplicationUser CreatedBy { get; set; }
[ForeignKey("LastModifiedById")]
public virtual ApplicationUser LastModifiedBy { get; set; }
如果您希望在关系的另一端引用 bi-directional,您可能需要将它们映射出来。例如,如果我想在我的 ApplicationUser class:
中使用“CreatedOrders”public class ApplicationUser
{
// ...
public virtual ICollection<Order> CreatedOrders { get; set; } = new List<Order>();
}
现在通常最好告诉 EF 将其关联到什么,因为 Order 有两个对应用程序用户的引用。同样,这可以在关系的任何一方完成。所以在返回我们订单的情况下 class:
[ForeignKey("CreatedById"), InverseProperty("CreatedOrders")]
public virtual ApplicationUser CreatedBy { get; set; }
这告诉 EF 此记录上的 CreatedBy 是访问 CreatedOrders 的订单时要使用的 link。
回到你的例子,有点令人困惑为什么 ApplicationUser 会包含一个库的集合,而一个订单期望一个“库”是一个用户。