我有一个解析某个网站的任务。在解析了一些帖子后,我有一个复杂的对象Post有很多评论,其中每个评论都有用户写过它而一些答案以其他评论的形式出现。实际上,类的结构会更复杂,但是,这里是示例(一些属性被遗漏,没有必要):
public class Post : IParsedEntity
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
public int Id { get; set; }
public string Title { get; set; }
public string Text { get; set; }
public User Author { get; set; }
public IList<Comment> DownLevelComments { get; set; }
public IList<Comment> AllComments { get; set; }
public Post()
{
DownLevelComments = new List<Comment>();
AllComments = new List<Comment>();
}
}
public class User : IParsedEntity
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
public string Name { get; set; }
public string Url { get; set; }
}
public class Comment : IParsedEntity
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
public int Id { get; set; }
public Post Post { get; set; }
public User Author { get; set; }
public Comment ParentComment { get; set; }
public string Text { get; set; }
public IList<Comment> SubComments { get; set; }
public Comment()
{
SubComments = new List<Comment>();
}
}
现在我配置我的数据库上下文:
modelBuilder.Entity<Comment>().HasRequired(c => c.Post).WithMany(c => c.AllComments);
modelBuilder.Entity<Post>().HasMany(c => c.DownLevelComments);
modelBuilder.Entity<Comment>().HasMany<Comment>(c => c.SubComments).WithOptional(c => c.ParentComment);
好的,我已经解析了一个帖子,现在我有一个Post实例,其中很多其他类的实例链接到post的主实例。
第一个问题:现在我有一个项目的多个实例('nsinreal'有两个注释,所以我有重复的用户实例)。如果我尝试添加Post i捕获异常,因为我有重复键的项目。好的,所以我需要编写自己的TryAdd方法来尝试添加实体和所有子项;我需要将具有相同主键的实例合并到一个实例;这一切都必须使用EF完成,因为我的代码可以解析不同的帖子,同一个用户可以出现在不同帖子的评论中。
第二个问题:我不能手动完成,因为它可能需要很长时间。我需要使用反射并使其自动运行。
第三个问题:解析和添加帖子必须在一台机器上使用不同的线程/任务。
目前我有递归函数TryAdd,它使得步骤:
不幸的是,这个算法在不同的线程上存在问题。我该如何重写呢?