Breeze:实体框架和NHibernate的多对多差异
情况如下:Breeze:实体框架和NHibernate的多对多差异,nhibernate,breeze,Nhibernate,Breeze,情况如下: WebApi v1 微风1.4.7 EF 5.0/NHibernate 3.3.1 我们想要的是:多对多暴露为多对一。一个客户可以有多个国家,一个国家可以有多个客户。已为此目的创建了ClientCountry实体 我的映射如下所示: 实体框架: modelBuilder.Entity<Client>().HasKey(p => p.Id).Property(p=>p.Id).HasDatabaseGeneratedOption(Databa
- WebApi v1
- 微风1.4.7
- EF 5.0/NHibernate 3.3.1
modelBuilder.Entity<Client>().HasKey(p => p.Id).Property(p=>p.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
modelBuilder.Entity<Client>().Property(p => p.Abbreviation);
modelBuilder.Entity<Client>().Property(p => p.ClientSinceDate).IsRequired();
modelBuilder.Entity<Client>().Property(p => p.ClientUntilDate);
modelBuilder.Entity<Client>().Property(p => p.Name).IsRequired();
modelBuilder.Entity<Client>().Property(p => p.Website);
modelBuilder.Entity<Client>().HasMany(p => p.Contacts).WithRequired(p => p.Client).WillCascadeOnDelete(true);
modelBuilder.Entity<Client>().HasMany(p => p.ClientCountries).WithRequired(p => p.Client).WillCascadeOnDelete(true);
modelBuilder.Entity<Contact>().HasKey(p => p.Id).Property(p => p.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
modelBuilder.Entity<Contact>().Property(p => p.Username);
modelBuilder.Entity<Contact>().HasRequired(p => p.Client);
modelBuilder.Entity<Country>().HasKey(p => p.Id).Property(p => p.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
modelBuilder.Entity<Country>().Property(p => p.ValidFrom);
modelBuilder.Entity<Country>().Property(p => p.ValidTo);
modelBuilder.Entity<Country>().Property(p => p.Code);
modelBuilder.Entity<Country>().Property(p => p.DefaultLabel);
modelBuilder.Entity<Country>().Property(p => p.Description);
modelBuilder.Entity<Country>().Property(p => p.DisplayOrder);
modelBuilder.Entity<ClientCountry>().HasKey(p => p.Id).Property(p => p.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
modelBuilder.Entity<ClientCountry>().Property(p => p.ValidFrom);
modelBuilder.Entity<ClientCountry>().Property(p => p.ValidTo);
modelBuilder.Entity<ClientCountry>().HasRequired(p => p.Client);
modelBuilder.Entity<ClientCountry>().HasRequired(p => p.Country);
问题:对于NHibernate,保存clientcountry会导致以下错误消息:“NOTNULL属性引用空值或暂时值CdT.EAI.DAL.clientcountry.Country”。有了EF,一切都按预期进行
我的代码有问题吗 因此,由于还没有反馈,我们采取了以下措施使其(或多或少)发挥作用:
- 首先,为了能够保存一个新的ClientCountry(使用暴露的连接表的多对多),我们必须这样做:
public class ClientCountryMap : BaseMapping<ClientCountry> { public ClientCountryMap() { Property(x => x.ValidFrom); Property(x => x.ValidTo); Property(x => x.ClientId, map => { map.Column("ClientId"); map.Insert(true); map.Update(true); map.NotNullable(true); }); Property(x => x.CountryId, map => { map.Column("CountryId"); map.Insert(true); map.Update(true); map.NotNullable(true); }); ManyToOne<Client>(x => x.Client, map => { map.Column("ClientId"); map.Cascade(Cascade.All); map.Insert(false); map.Update(false); map.NotNullable(true); }); ManyToOne<Country>(x => x.Country, map => { map.Column("CountryId"); map.Cascade(Cascade.All); map.Insert(false); map.Update(false); map.NotNullable(true); }); } }
这里的区别在于插入/更新是反向的<代码>插入(true)和公共类ClientCountryMap:BaseMapping { 公共客户端CountryMap() { 属性(x=>x.ValidFrom); 属性(x=>x.ValidTo); 属性(x=>x.ClientId,map=> { 地图栏(“客户ID”); map.Insert(true); 地图更新(真); map.NotNullable(true); }); 属性(x=>x.CountryId,map=> { 地图栏(“CountryId”); map.Insert(true); 地图更新(真); map.NotNullable(true); }); 多通(x=>x.客户端,映射=> { 地图栏(“客户ID”); map.Cascade(Cascade.All); 地图。插入(假); 地图更新(假); map.NotNullable(true); }); 多通(x=>x.国家,地图=> { 地图栏(“CountryId”); map.Cascade(Cascade.All); 地图。插入(假); 地图更新(假); map.NotNullable(true); }); } }
必须在外键映射上设置,而不是在关联上设置。在这一点上,它与以前的观点不同更新(true)
- 第二个是必须在每个集合关联上设置
,否则在更新父实体时将删除所有集合Inverse(true)
$scope.create = function (index) {
var c = $scope.clients[index];
var newClientCountry = breezeService.manager.createEntity('ClientCountry', {
ValidFrom: Date(2013, 01, 01),
ValidTo: Date(2015, 01, 01),
Client: c,
Country: country,
});
breezeService.manager.saveChanges()
.then(function (data) {
$log.info('client created');
})
.fail(function (dat) {
$log.error('save client failed:' + data)
})
}
public class ClientCountryMap : BaseMapping<ClientCountry>
{
public ClientCountryMap()
{
Property(x => x.ValidFrom);
Property(x => x.ValidTo);
Property(x => x.ClientId, map =>
{
map.Column("ClientId");
map.Insert(true);
map.Update(true);
map.NotNullable(true);
});
Property(x => x.CountryId, map =>
{
map.Column("CountryId");
map.Insert(true);
map.Update(true);
map.NotNullable(true);
});
ManyToOne<Client>(x => x.Client, map =>
{
map.Column("ClientId");
map.Cascade(Cascade.All);
map.Insert(false);
map.Update(false);
map.NotNullable(true);
});
ManyToOne<Country>(x => x.Country, map =>
{
map.Column("CountryId");
map.Cascade(Cascade.All);
map.Insert(false);
map.Update(false);
map.NotNullable(true);
});
}
}