(DTO と AutoMapper を使用して) 機能する解決策を見つけました。これを以下に再現しますが、問題に対するさまざまなアプローチを例とともにリストした回答を希望します。これは、受け取った場合は回答としてマークされます。
私のエンティティ モデルには、子エンティティから親エンティティに移動するナビゲーション プロパティがあります。私のプロジェクトは順調に機能していました。その後、単体テストに AutoFixture を使用し始めましたが、テストは失敗し、AutoFixture は循環参照があると言いました。
ここで、このような循環参照ナビゲーション プロパティは Entity Framework 内で問題ないことに気付きましたが、この投稿 ( AutoFixture で複雑な子を作成するときに親プロパティの値を使用する) を見つけました。ここで、AutoFixture の作成者である Mark Seemann は次のように述べています。
「記録のために、私は何年も循環参照を使用して API を作成していないため、これらの親子関係を回避することは十分に可能です。」
したがって、子/親の関係を回避するためにドメイン モデルをリファクタリングする方法を理解したいと思います。
以下は、問題のエンティティ クラス、リポジトリ メソッド、およびビューで循環参照を引き起こすプロパティの使用方法です。 完璧な答えは、例を挙げて選択できるさまざまなオプションと、各アプローチの基本的な長所/短所を説明することです.
注: 循環参照の原因となっているプロパティは、UserTeam モデルの User です。
モデル:
public class UserProfile
{
public UserProfile()
{
UserTeams = new HashSet<UserTeam>();
Games = new HashSet<Game>();
}
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
public virtual ICollection<UserTeam> UserTeams { get; set; }
public virtual ICollection<Game> Games { get; set; }
}
public class Game
{
public Game()
{
UserTeams = new HashSet<UserTeam>();
}
public int Id { get; set; }
public int CreatorId { get; set; }
public virtual ICollection<UserTeam> UserTeams { get; set; }
}
public class UserTeam
{
public UserTeam()
{
UserTeam_Players = new HashSet<UserTeam_Player>();
}
public int Id { get; set; }
public int UserId { get; set; }
public int GameId { get; set; }
public virtual UserProfile User { get; set; }
public virtual ICollection<UserTeam_Player> UserTeam_Players { get; set; }
}
リポジトリ方式
public IEnumerable<Game> GetAllGames()
{
using (DataContext)
{
var _games = DataContext.Games
.Include(x => x.UserTeams)
.Include(x => x.UserTeams.Select(y => y.User))
.ToList();
if (_games == null)
{
// log error
return null;
}
return _games;
}
}
意見
@model IEnumerable<Game>
@foreach (var item in Model){
foreach (var userteam in item.UserTeams){
<p>@userteam.User.UserName</p>
}
}
ここで、「ユーザー」ナビゲーション プロパティを削除すると、「@userteam.User.UserName」を実行できなくなります。
では、ドメイン モデルをリファクタリングして循環参照を削除し、ゲームを簡単にループして UserTeam.User.Username のようなことを行うにはどうすればよいでしょうか?