如何在ASP.Net MVC Entity Framework 6项目中创建Value-Objects?

问题描述:

有班在我的测试应用程序:如何在ASP.Net MVC Entity Framework 6项目中创建Value-Objects?

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 init的数据:

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

我得到异常:“模型生成过程中检测到一个或多个验证错误:DomainDrivenWeb.Models.Currency:名称:模式中的每种类型的名称必须是唯一的。类型名称'货币'已经定义。

+0

'公众货币货币{get;私人设置; }'请尝试在这里使用不同的变量名称,例如'public Currency _currency {get;私人设置; ''或'货币'以外的其他东西。 –

+0

答案出现在错误消息中。 –

+0

我改变了货币货币{get;私人设置; } Currency CurrencyCurrency {get;私人设置; },但得到了同样的例外。 – Oblomingo

这里的问题是,你处理Currency同时作为的ValueObject和实体

这一行:。

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

告诉EF的Currency类型是隐含的复杂类型Move实体 - 嵌套在Price属性中(类型为Money)。这更像是一个ValueObject。

但是

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

告诉EF把它作为一个实体。

这就是为什么错误消息说Each type name in a schema must be unique. Type name 'Currency' is already defined. - 当需要将货币模型设置为实体时,类型名称货币已被定义为Movie实体上的复合类型。

如果您删除其中一个配置行,那么错误应该消失 - 但它不会真正解决您的问题,因为您需要考虑 - 在您的域中是Currency真正的实体或ValueObject ?

Movie具有己Currency类型的属性MoneyPrice - 这种用法意味着它是一个的ValueObject。但该班有Id字段 - “身份”的存在意味着它是一个实体。

你需要考虑通过域建模和体现在这些类型的探索应该如何真正要处理的业务流程。