0

いくつかのサイトを解析するタスクがあります。いくつかの投稿を解析した後、私は多くのコメントを持つ複雑なオブジェクト 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>();
    }
}

次に、db コンテキストを構成します。

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

さて、1 つの投稿を解析しました。これで、Post のインスタンスが 1 つになり、他のクラスのインスタンスが多数、post のメイン インスタンスにリンクされました。

最初の問題: 1 つのアイテムのインスタンスが複数あります (「nsinreal」から 2 つのコメントがあったため、ユーザー インスタンスが重複しています)。投稿を追加しようとすると、キーが重複しているアイテムがあるため、例外が発生しました。では、エンティティとすべてのサブ項目を追加しようとする独自の TryAdd メソッドを作成する必要があります。主キーが等しいインスタンスを 1 つのインスタンスにマージする必要があります。私のコードはさまざまな投稿を解析でき、同じユーザーがさまざまな投稿のコメントに表示される可能性があるため、EFを使用してこれを行う必要があります。

2 番目の問題: 時間がかかるため、手動で行うことはできません。リフレクションを使用して、自動的に機能させる必要があります。

3 番目の問題: 投稿の解析と追加では、1 台のマシンで異なるスレッド/タスクを使用する必要があります。

現在、再帰関数 TryAdd があり、次の手順を実行します。

  1. エンティティがまだコンテキストにないことを確認してください
  2. エンティティの Foreach プロパティ (プリミティブな IParsedEntity クラスのみ) は、次のことを行います。
    1. エンティティから削除して、すべてのプロパティを持つすべてのエンティティの自動挿入を防ぎます。投稿に少なくとも 2 回表示される解析済みユーザーのような重複がある場合、それは悪いことです。
    2. プロパティの値をデータベース コンテキストに追加して、答えを暗記してみてください。リフレクション マジックを使用して、ジェネリック メソッドで通常の作業を提供する必要があります
    3. データベースの回答またはプロパティの元の値を特別な辞書にプッシュします
  3. IList の同じアクション
  4. コンテキストに項目を追加
  5. 現在のアイテムのすべてのプロパティとリストを復元する
  6. ローカルの変更をデータベースに一度だけ保存する

残念ながら、このアルゴリズムには別のスレッドで問題があります。どのように書き直せばいいですか?

4

0 に答える 0