我想通过代码使用NHibernate映射来映射具有类型ICollection<>
的属性的类。以下代码有效。但是我不喜欢Person
中的额外CarSet
属性来使映射工作。
public class PersonSet
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual ICollection<CarSet> Cars { get; set; }
}
public class CarSet
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual PersonSet Person { get; set; }
}
public class PersonSetMap : ClassMapping<PersonSet>
{
public PersonSetMap()
{
Id(x => x.Id, m=>m.Generator(Generators.Identity));
Property(x=>x.Name);
Set(x => x.Cars, c =>
{
c.Key(k =>
{
k.Column("PersonId");
});
c.Cascade(Cascade.Persist);
c.Lazy(CollectionLazy.NoLazy);
}, r =>
{
r.OneToMany();
}
);
}
}
public class CarSetMap : ClassMapping<CarSet>
{
public CarSetMap()
{
Id(x => x.Id, m => m.Generator(Generators.Identity));
Property(x => x.Name);
ManyToOne(x => x.Person, m =>
{
m.Column("PersonId");
m.Cascade(Cascade.None);
m.NotNullable(true);
});
}
}
public void Save(){
using (var session = Cfg.Session)
using (var tx = session.BeginTransaction())
{
PersonSet John = new PersonSet { Name = PersonName.John };
John.Cars = new List<CarSet> {
new CarSet { Name = CarnName.BMW,Person = John},
new CarSet { Name = CarnName.BM,Person = John }};
session.Save(entity);
tx.Commit();
}
}
上面的代码生成以下SQL脚本:
create table PersonSet (
Id INT IDENTITY NOT NULL,
Name NVARCHAR(255) null,
primary key (Id)
)
create table CarSet (
Id INT IDENTITY NOT NULL,
Name NVARCHAR(255) null,
PersonId INT not null,
primary key (id)
)
alter table CarSet
add constraint FKF967D6489A220265
foreign key (PersonId)
references PersonSet
我想要的是生成如下所示差异的SQL脚本,并保持其余部分相同:
create table CarSet (
Name NVARCHAR(255) null,
PersonId INT not null,
)
理想情况下,我想要这样的CarSet
:
public class CarSet
{
public virtual int PersonId { get; set; }
public virtual string Name { get; set; }
}
有什么想法吗?
答案 0 :(得分:0)
将Cars映射为ComponentCollection
class Person
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<Car> Cars { get; set; }
}
class Car
{
public virtual Person Owner { get; set; }
public virtual string Name { get; set; }
}
public class PersonMap : ClassMapping<Person>
{
public PersonMap()
{
Id(x => x.Id, m => m.Generator(Generators.Identity));
Property(x => x.Name);
Set(x => x.Cars, c =>
{
c.Key(k => k.Column("PersonId"));
c.Cascade(NHibernate.Mapping.ByCode.Cascade.Persist);
c.Lazy(CollectionLazy.NoLazy);
}, r =>
{
r.Component(c =>
{
c.Parent(x => x.Owner);
c.Property(x => x.Name);
});
});
}
}
答案 1 :(得分:0)
您的理想解决方案是不可能的。要使用没有自己的ID列的CarSet表,它必须是一个组件,但组件集不能有可为空的列。如果您可以将Name
标记为非空,则可以调整Firo发布的解决方案。
如果不行,您至少可以解决第一个删除Person
属性的请求。只需删除属性并将集合映射中的键列标记为不可为空。 CarSet
仍然是一个实体(因此拥有自己的ID),但您不需要在代码中引用PersonSet
。
顺便问一下,为什么你的课程后缀为Set
?只需将它们命名为Person
和Car
会更好,因为它们只代表一个人或汽车,而不是它们的集合。