我想映射以下简单实体:
public class AnimalsOwner
{
public AnimalsOwner()
{
Cats = new List<Cat>();
Dogs = new List<Dog>();
}
public virtual int Id { get; set; }
public virtual IList<Cat> Cats { get; set; }
public virtual IList<Dog> Dogs { get; set; }
}
public abstract class Animal
{
public virtual int Id { get; set; }
public virtual AnimalsOwner AnimalsOwner { get; set; }
}
public class Dog : Animal
{
public virtual string DogsProperty { get; set; }
}
public class Cat : Animal
{
public virtual string CatsProperty { get; set; }
}
使用以下映射:
public OwnerMapping()
{
this.Table("Owners");
Id(x => x.Id)
.GeneratedBy.Native();
HasMany(x => x.Cats).AsBag().Cascade.SaveUpdate();
HasMany(x => x.Dogs).AsBag().Cascade.SaveUpdate();
}
}
public class AnimalMapping : ClassMap<Animal>
{
public AnimalMapping()
{
this.Table("Animals");
Id(x => x.Id).GeneratedBy.Native();
References(x => x.AnimalsOwner).Not.Nullable();
}
}
public class DogMap : SubclassMap<Dog>
{
public DogMap()
{
this.Table("Dogs");
this.KeyColumn("AnimalId");
Map(x => x.DogsProperty);
}
}
public class CatMap : SubclassMap<Cat>
{
public CatMap()
{
this.Table("Cats");
this.KeyColumn("AnimalId");
Map(x => x.CatsProperty);
}
}
使用这样的映射一切正常,但生成的模式如下所示:
这样的代码:
var owner = new AnimalsOwner();
owner.Cats.Add(new Cat()
{
AnimalsOwner = owner,
CatsProperty = "cat"
});
在列OwnderId的所有三个表(动物,猫,狗)中插入。但是仅仅在动物表中使用它还不够吗?如果是,那么如何实现呢?如果NHibernate按预期运行,那他为什么要这么重复?
答案 0 :(得分:3)
我会使用每个表的策略映射它,并按类型过滤公共集合。这种数据库结构更易于使用,查询效率更高。
public class AnimalMapping : ClassMap<Animal>
{
public AnimalMapping()
{
Table("Animals");
Id(x => x.Id).GeneratedBy.Native();
References(x => x.AnimalsOwner);
DiscriminateSubClassesOnColumn("AnimalType");
}
}
public class DogMap : SubclassMap<Dog>
{
public DogMap()
{
DiscriminatorValue("DOG");
Map(x => x.DogsProperty);
}
}
public class CatMap : SubclassMap<Cat>
{
public CatMap()
{
DiscriminatorValue("CAT");
Map(x => x.CatsProperty);
}
}
Dogs and Cats集合可以通过将Animals集合映射为私有成员并按类型过滤来公开:
public class AnimalsOwner
{
private IList<Animal> _animals;
public AnimalsOwner()
{
_animals = new List<Animal>();
}
public virtual int Id { get; set; }
public virtual IEnumerable<Animal> Animals { get { return _animals; } }
public virtual IEnumerable<Cat> Cats { get { return _animals.OfType<Cat>(); } }
public virtual IEnumerable<Dog> Dogs { get { return _animals.OfType<Dog>(); } }
public virtual void AddAnimal(Animal animal)
{
if (!_animals.Contains(animal))
{
animal.AnimalsOwner = this;
_animals.Add(animal);
}
}
public virtual void RemoveAnimal(Animal animal)
{
if (_animals.Contains(animal))
{
animal.AnimalsOwner = null;
_animals.Remove(animal);
|
}
}
此课程的映射是:
public OwnerMapping()
{
this.Table("Owners");
Id(x => x.Id).GeneratedBy.Native();
HasMany(x => x.Animals.AsBag.Cascade.AllDeleteOrphan()
.Inverse().LazyLoad()
.Access.CamelCaseField(Prefix.Underscore);
}
}
添加猫的代码是:
var owner = new AnimalsOwner();
owner.AddAnimal(new Cat()
{
CatsProperty = "cat"
});
答案 1 :(得分:0)
您将获得重复项,因为您在所有者映射中定义了HasMany Cats and Dogs(以及Owner类中的Cat&amp; Dog集合)。也许您真正想要的是所有者类中的动物集合(不是单独的狗和猫)以及所有者映射中的一个HasMany动物?