0

ICollection<>我想通过代码使用 NHibernate 映射来映射具有类型属性的类。下面的代码有效。但我不喜欢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; }

}

任何想法?

4

2 回答 2

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);
            });
        });
    }
}
于 2013-05-13T09:55:32.163 回答
0

您的理想解决方案是不可能的。要使用没有自己的 ID 列的 CarSet 表,它必须是一个组件,但组件集不能有可为空的列。如果您可以标记Name为非空,您可以调整 Firo 发布的解决方案。

如果这不行,您至少可以解决您的第一个删除Person属性的请求。只需删除该属性并将您的集合映射中的键列标记为不可为空。CarSet仍将是一个实体(因此有自己的 ID),但您不需要PersonSet在代码中引用。

顺便说一句,为什么你的课程后缀是Set?只是命名它们PersonCar更好,因为它们只代表一个人或一辆车,而不是它们的集合。

于 2013-05-14T06:37:54.467 回答