C# Entity Framework 一对多关系,自定义key
C# Entity Framework one-to-many relationships, custom key
我在 EF 数据库代码中基于一个简单的外键定义了一个良好的自动一对多关系。
public class MyCategory
{
public int Id { get; set; }
public MyItems Items { get; set; }
}
public class MyItems : List<MyItem> { }
public class MyItem
{
public int Id { get; set; }
public int MyCategoryId { get; set; }
public string ItemsContents { get; set; }
}
这样,每当我向数据库添加新的 MyCategory
并使用 SaveChanges()
时,它会自动将所有 MyItem
(s) 的相关列表添加到相应的 MyItems数据库 table。
现在,我的领导提出了一个新要求,即外键是一个不同的非自动索引 int
属性,而不是 Id
,以防 table 被重建并且索引 ID 丢失。所以我们想出了以下内容:
public class MyCategory
{
public int Id { get; set; }
public int MyCategoryId { get; set; }
public MyItems Items { get; set; }
}
public class MyItems : List<MyItem> { }
public class MyItem
{
public int Id { get; set; }
public int MyCategoryId { get; set; }
public string ItemsContents { get; set; }
}
新想法是在 'one' table 中使用与在 'many' table 中使用的同名密钥。据推测,MyCategoryId
将被提供给 MyCategory
对象,因为它被设置到数据库中,并且所有 MyItem
(s) 将像以前一样自动添加,但它们的 MyCategoryId
与 MyCategory
相同。
问题是,MyItem
的 MyCategoryId
仍在从 MyCategory
的 Id
中拉出。我尝试将 [ForeignKey]
属性放在各处,并使用 OnModelCreating(DbModelBuilder modelBuilder)
将 MyCategory.MyCategoryId
显式映射到 MyItem.MyCategoryId
,但没有取得成功,需要任何人在 Whosebug 上提供帮助谁知道。谢谢!
这是我试图用来实际添加记录的函数。
private void AddMyCategory(MyCategory myCat)
{
int prevId = 0;
var prevFoundMyCategory = _context.MyCategories.OrderByDescending(m => m.MyCategoryId).Take(1);
if(prevFoundMyCategory.FirstOrDefault() != null)
{
prevId = prevFoundMyCategory.First().MyCategoryId;
}
int nextId = prevId + 1;
myCat.MyCategoryId = nextId;
_context.MyCategories.Add(myCat);
_context.SaveChanges();
}
你可以说,如果可以让 EF 自动执行此操作,我会尽量避免这一行:
foreach(var x in myCat.Items)
{
x.MyCategoryId = nextId;
}
实际上,不,即使这样设置也不起作用,因为 EF 会覆盖我设置的任何内容,Id
属性 MyCategory
...
好吧,ForeignKey 和虚拟集合让我完成了一半,但我错过了正确位置的 [Key] 属性!最后它应该看起来更像:
public class MyCategory
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Key]
public int MyCategoryId { get; set; }
public List<MyItem> Items { get; set; }
}
public class MyItem
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public int MyCategoryId { get; set; }
public string ItemsContents { get; set; }
[ForeignKey("MyCategoryId")]
public virtual MyCategory MyCategory { get; set; }
}
我在 EF 数据库代码中基于一个简单的外键定义了一个良好的自动一对多关系。
public class MyCategory
{
public int Id { get; set; }
public MyItems Items { get; set; }
}
public class MyItems : List<MyItem> { }
public class MyItem
{
public int Id { get; set; }
public int MyCategoryId { get; set; }
public string ItemsContents { get; set; }
}
这样,每当我向数据库添加新的 MyCategory
并使用 SaveChanges()
时,它会自动将所有 MyItem
(s) 的相关列表添加到相应的 MyItems数据库 table。
现在,我的领导提出了一个新要求,即外键是一个不同的非自动索引 int
属性,而不是 Id
,以防 table 被重建并且索引 ID 丢失。所以我们想出了以下内容:
public class MyCategory
{
public int Id { get; set; }
public int MyCategoryId { get; set; }
public MyItems Items { get; set; }
}
public class MyItems : List<MyItem> { }
public class MyItem
{
public int Id { get; set; }
public int MyCategoryId { get; set; }
public string ItemsContents { get; set; }
}
新想法是在 'one' table 中使用与在 'many' table 中使用的同名密钥。据推测,MyCategoryId
将被提供给 MyCategory
对象,因为它被设置到数据库中,并且所有 MyItem
(s) 将像以前一样自动添加,但它们的 MyCategoryId
与 MyCategory
相同。
问题是,MyItem
的 MyCategoryId
仍在从 MyCategory
的 Id
中拉出。我尝试将 [ForeignKey]
属性放在各处,并使用 OnModelCreating(DbModelBuilder modelBuilder)
将 MyCategory.MyCategoryId
显式映射到 MyItem.MyCategoryId
,但没有取得成功,需要任何人在 Whosebug 上提供帮助谁知道。谢谢!
这是我试图用来实际添加记录的函数。
private void AddMyCategory(MyCategory myCat)
{
int prevId = 0;
var prevFoundMyCategory = _context.MyCategories.OrderByDescending(m => m.MyCategoryId).Take(1);
if(prevFoundMyCategory.FirstOrDefault() != null)
{
prevId = prevFoundMyCategory.First().MyCategoryId;
}
int nextId = prevId + 1;
myCat.MyCategoryId = nextId;
_context.MyCategories.Add(myCat);
_context.SaveChanges();
}
你可以说,如果可以让 EF 自动执行此操作,我会尽量避免这一行:
foreach(var x in myCat.Items)
{
x.MyCategoryId = nextId;
}
实际上,不,即使这样设置也不起作用,因为 EF 会覆盖我设置的任何内容,Id
属性 MyCategory
...
好吧,ForeignKey 和虚拟集合让我完成了一半,但我错过了正确位置的 [Key] 属性!最后它应该看起来更像:
public class MyCategory
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Key]
public int MyCategoryId { get; set; }
public List<MyItem> Items { get; set; }
}
public class MyItem
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public int MyCategoryId { get; set; }
public string ItemsContents { get; set; }
[ForeignKey("MyCategoryId")]
public virtual MyCategory MyCategory { get; set; }
}