使用ASP.NET Core 2.1和Entity Framework Core 2.1,我具有以下实体:
public class Category {
public Int32 Id { get; set; }
public String Name { get; set; }
}
public class Post {
public Int32 Id { get; set; }
public Int32 CategoryId { get; set; }
public String Title { get; set; }
public String Content { get; set; }
public virtual Category Category { get; set; }
}
对于播种类别,我有以下内容:
modelBuilder.Entity<Category>().HasData(
new { Id = 1, Name = "Reading" },
new { Id = 2, Name = "Travelling" }
);
但是,对于种子发布,我从YML文件中获取数据:
var posts = _service.GetPostsFromYMLFiles(path);
modelBuilder.Entity<Post>().HasData(posts);
posts
来自YML文件,其内容如下:
new { CategoryName = "Reading", Title = "A", Content = "A Content" },
new { CategoryName = "Travelling", Title = "B", Content = "B Content" }
这些YML文件是由第三方创建的,我无法更改它们。
要播种这些帖子,我相信我需要:
步骤(2)似乎很简单,但是如何完成步骤(1)?
答案 0 :(得分:1)
我认为我需要播种这些帖子
获取每个CategoryName的对应类别ID;
为每个帖子生成一个ID。
是的!你是对的!您必须在CategoryId
中使用CategoryName
而不是Post
,因为CategoryId
是关系密钥,而不是CategoryName
。因此,您的YML内容应如下所示:
new {Id = 1, CategoryId = 1, Title = "A", Content = "A Content" },
new {Id = 2, CategoryId = 2, Title = "B", Content = "B Content" }
然后在OnModelCreating
的{{1}}中进行如下操作:
DbConext
这些YML文件是由第三方创建的,我无法更改它们。
然后,您必须编写一种自定义服务方法,在其中使用protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
var posts = _service.GetPostsFromYMLFiles(path);
modelBuilder.Entity<Category>().HasData(
new { Id = 1, Name = "Reading"},
new { Id = 2, Name = "Travelling" }
);
modelBuilder.Entity<Post>().HasData(posts);
}
检查YMl文件中的每个帖子,然后必须制作CategoryName
的新列表,并在其中替换为Post
CategoryName
及其适当的值,如下所示:
CateogryId
然后在public class YmlPost
{
public string CategoryName { get; set; }
public string Title { get; set; }
public string Content { get; set; }
}
public class SeedDataService
{
static List<Category> categoryList = new List<Category>()
{
new Category { Id = 1, Name = "Reading" },
new Category { Id = 2, Name = "Traveling" }
};
public static List<Category> GetCategoriesForSeeding()
{
return categoryList;
}
public static List<Post> GetPostsForSeeding()
{
List<YmlPost> postListFromYML = _service.GetPostsFromYMLFiles(path);
List<Post> posts = postListFromYML.Select((p, i) => new Post
{
Id = i+1, // index is 0 based that's why you have to add 1.
Title = p.Title,
Content = p.Content,
CategoryId = categoryList.Single(c => c.Name ==
p.CategoryName).Id
}).ToList();
return posts;
}
}
的{{1}}中进行如下操作:
OnModelCreating
答案 1 :(得分:1)
代替将类别播种到位,而是先将它们保存到变量中:
onMessageReceived
然后,将其传递给var categories = new[]
{
new Category { Id = 1, Name = "Reading" },
new Category { Id = 2, Name = "Traveling" }
};
:
HasData
有了它,您现在可以在将YML数据映射到modelBuilder.Entity<Category>().HasData(categories);
实体时查询内存中的此列表以获取相关类别:
Post
var posts = _service.GetPostsFromYMLFiles(path);
modelBuilder.Entity<Post>().HasData(posts.Select((p, i) => new Post
{
Id = i,
Title = p.Title,
Content = p.Content,
CategoryId = categories.Single(c => c.Name == p.CategoryName).Id
});
是不可为空的,因此,如果YML中命名的特定类别实际上不存在,则可能要创建一个后备。您甚至可以考虑从YML帖子中播种类别本身,以确保其中的所有内容确实存在:
CategoryId