0

は私のテストアプリケーションのクラスがあります。初期化データのASP.Net MVC、Entity Framework 6プロジェクトでバリューオブジェクトを作成するには?

public class ApplicationDbContext : IdentityDbContext<ApplicationUser> 
{ 
    public ApplicationDbContext() 
     : base("DefaultConnection", throwIfV1Schema: false) 
    { 
     Database.SetInitializer<ApplicationDbContext>(new MovieContextInitializer()); 
    } 

    public DbSet<Movie> Movies { get; set; } 
    public DbSet<Currency> Currencies { get; set; } 

    public static ApplicationDbContext Create() 
    { 
     return new ApplicationDbContext(); 
    } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Types<Movie>() 
     .Configure(ctc => ctc.Property(m => m.Price.Amount).HasColumnName("MoviePriceAmount")); 

     modelBuilder.Types<Movie>() 
     .Configure(ctc => ctc.Property(m => m.Price.Currency.Id).HasColumnName("MoviePriceCurrency")); 

     base.OnModelCreating(modelBuilder); 
    } 
} 

MovieContextInitializer:

public class MovieContextInitializer : DropCreateDatabaseIfModelChanges<ApplicationDbContext> 
{ 
    protected override void Seed(ApplicationDbContext context) 
    { 
     var usdCurrency = new Currency {Id = 1, Name = "USD"}; 
     var euroCurrency = new Currency {Id = 2, Name = "EUR"}; 

     context.Currencies.Add(usdCurrency); 
     context.Currencies.Add(euroCurrency); 

     context.Movies.Add(new Movie 
     { 
      Title = "GhoustBusters", 
      Genre = "Comedy", 
      ReleaseDate = new DateTime(2016, 9, 10), 
      Price = new Money(50, usdCurrency) 
     }); 

     context.Movies.Add(new Movie 
     { 
      Title = "Matrix", 
      Genre = "Action", 
      ReleaseDate = new DateTime(2010, 2, 10), 
      Price = new Money(40, euroCurrency) 
     }); 
    } 
} 

そして、私のエンティティと値がオブジェクトクラス:

public class Movie 
{ 
    public int Id { get; set; } 
    public string Title { get; set; } 
    public DateTime ReleaseDate { get; set; } 
    public string Genre { get; set; } 
    public Money Price { get; set; } 
} 
public class Currency 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
} 
[ComplexType] 
public class Money 
{ 
    public Money(int amount, Currency currency) 
    { 
     Amount = amount; 
     Currency = currency; 
    } 
    public int Amount { get; private set; } 
    public Currency Currency { get; private set; } 
} 

私が呼んしようとしています:

ApplicationDbContext db = new ApplicationDbContext(); 
var movies = db.Movies.ToList() 

例外を受け取りました: "モデル生成中に1つ以上の検証エラーが検出されました:DomainDrivenWeb.Models.Currency:Name:スキーマ内の各タイプ名は一意である必要があります。タイプ名 '通貨'はすでに定義されています。

+0

'public Currency Currency {get;プライベートセット; } 'ここでは、別の変数名を使用してみてください。たとえば、' public Currency _currency {get;プライベートセット; } 'または' Currency'以外のもの。 –

+0

答えはエラーメッセージです。 –

+0

私は通貨通貨を変更しました{get;プライベートセット; }を通貨に換算します。プライベートセット; }、同じ例外がありました。 – Oblomingo

答えて

2

ここでの問題は、あなたがValueObjectとエンティティの両方としてCurrency治療しているということです

この行:。。

modelBuilder.Types<Movie>() 
    .Configure(ctc => ctc.Property(m => m.Price.Currency.Id).HasColumnName("MoviePriceCurrency")); 

Currency型が暗黙的に複合型であることをEFに指示しますMoveのエンティティ - 価格プロパティ(タイプMoney)にネストされています。これはValueObjectに似ています。

しかし

public DbSet<Currency> Currencies { get; set; } 

EFにエンティティとして扱うように指示します。

というエラーメッセージが表示されます - エンティティとして通貨のモデルを設定するときに、タイプ名通貨はMovieエンティティの複合タイプとして既に定義されています。

これらの設定行のいずれかを削除した場合、エラーは消えてしまうはずですが、実際にはあなたのドメイン内のCurrencyが実際にEntityかValueObject ?この使用は、それがValueObjectある意味 -

MovieCurrencyの性質を有するタイプMoneyPrice有します。しかし、クラスにはIdフィールドがあります。「同一性」の存在は、それがエンティティであることを意味します。

実際にどのように扱うべきかを調べるには、ドメインモデリングとこれらのタイプに組み込まれているビジネスプロセスを考える必要があります。

関連する問題