我正在使用Nhibernate 3.2 GA,我正在按代码进行映射。
我有一个带有2个组件的简单类:
public class Organization : EntityBase
{
public Organization()
{
Users = new List<User>();
BankAccounts = new List<BankAccount>();
}
[Required]
public virtual Guid ExternalID { set; get; }
[Required]
public virtual Int64 Number { set; get; }
[Required]
public virtual string Name { set; get; }
public virtual Person Contact { set; get; }
public virtual Address Address { set; get; }
[Required]
[DataType(DataType.EmailAddress)]
public virtual string Email { set; get; }
[DataType(DataType.Url)]
public virtual string Website { set; get; }
public virtual IList<BankAccount> BankAccounts { set; get; }
public virtual IList<User> Users { set; get; }
}
实体在没有组件的情况下成功保存。
然而,当我检索实体并尝试更新组件时,没有真正发生的事情!
这是映射代码:
var mapper = new ConventionModelMapper();
var entityBaseType = typeof(EntityBase);
// define root entity and ignore base from being mapped.
mapper.IsEntity((t, declared) => entityBaseType.IsAssignableFrom(t) && !t.IsInterface && !t.IsAbstract);
mapper.IsRootEntity((t, declared) => entityBaseType.Equals(t.BaseType)
|| t.BaseType == typeof(InvoiceBase)
|| t.BaseType == typeof(InvoiceItemBase));
mapper.IsComponent((t, declared) => t.Namespace.EndsWith("Components"));
// column naming and cascading configuration
mapper.BeforeMapManyToOne += (insp, prop, map) => map.Column(prop.LocalMember.GetPropertyOrFieldType().Name + "Id");
mapper.BeforeMapManyToOne += (insp, prop, map) => map.Cascade(Cascade.Persist);
mapper.BeforeMapBag += (insp, prop, map) => map.Key(km => km.Column(prop.GetContainerEntity(insp).Name + "Id"));
mapper.BeforeMapBag += (insp, prop, map) => map.Cascade(Cascade.All);
// enitity class mapping
mapper.Class<EntityBase>(map => {
map.Id(e => e.ID, m => m.Generator(Generators.Identity));
map.Property(e => e.CreatedOn);
map.Property(e => e.DeletedOn);
map.Property(e => e.UpdatedOn);
map.ManyToOne<User>(e => e.CreatedBy, m => { m.Column("CreatedBy"); });
map.ManyToOne<User>(e => e.DeletedBy, m => { m.Column("DeletedBy"); });
map.ManyToOne<User>(e => e.UpdateBy, m => { m.Column("UpdateBy"); });
});
//define components
mapper.Component<Person>(map => {
map.Property(p => p.Email, m => m.Column("Preson_Email"));
map.Property(p => p.Name, m => m.Column("Preson_Name"));
map.Property(p => p.Surname, m => m.Column("Preson_Surname"));
map.Insert(true);
map.Update(true);
});
mapper.Component<Address>(map => {
map.Property(a => a.City, m => m.Column("Address_City"));
map.Property(a => a.Street, m => m.Column("Address_Street"));
map.Property(a => a.Zipcode, m => m.Column("Address_Zipcode"));
map.Insert(true);
map.Update(true);
});
//TODO: move to different class (cleaner)
//all entities mapping
mapper.Class<User>(map => {
map.ManyToOne(u => u.Organization);
});
mapper.Class<Organization>(map => {
map.Component<Person>(o => o.Contact);
map.Component<Address>(o => o.Address);
map.Bag<User>(o => o.Users, cm => cm.Inverse(true), r => { });
});
var mapping = mapper.CompileMappingFor(entityBaseType.Assembly.GetExportedTypes().Where(t => t.Namespace.EndsWith("Domain")));
以下是我如何保存到数据库:
// get user domain object
var user = UserService.GetById((int)membershipUser.ProviderUserKey);
// get the organization to continue the profile
var organization = OrganizationService.GetByExternalId(model.ExternalID);
organization.Address = new Address
{
City = model.OrganizationAddressCity,
Street = model.OrganizationAddressStreet,
Zipcode = model.OrganizationAddressZip
};
organization.Contact = new Person
{
Email = model.OrganizationContactEmail,
Name = model.OrganizationContactName,
Surname = model.OrganizationContactSurname
};
//organization.CreatedBy = user;
organization.UpdatedOn = DateTime.Now;
// add the user to the organization
organization.Users.Add(user);
//save organization profile
OrganizationService.Update(organization);
使用Spring.Net事务管理的组织存储库:
[Transaction]
public virtual void Update(T entity)
{
entity.UpdatedOn = DateTime.Now;
Session.Update(entity);
}
注意:使用Spring.Net事务管理修饰的方法,所以我没有显式调用Commit。
答案 0 :(得分:0)
好的,它与映射无关。映射是正确的!
这是Spring Transaction的故障,不确定是否是我配置Spring.Net SessionFactory的错误。
解决方法是明确调用:
Session.Flush();