流畅的NHibernate - HasOne映射到ReferencesAny

时间:2013-05-03 02:15:42

标签: nhibernate fluent has-one

我有以下POCO课程:

public class Container
{
    public virtual Int64 ContainerId { get; protected set; }
    public virtual string Name { get; set; }
    public virtual Location Location { get; set; }
}

public abstract class Location
{
    public virtual Int64 LocationId { get; protected set; }
    public virtual string Name { get; set; }
}

public class UniqueLocation : Location
{
    public virtual Container Container { get; set; }
}

public class SharedLocation : Location
{
    public SharedLocation()
    {
        this.Containers = new List<Container>();
    }

    public virtual IList<Container> Containers { get; set; }
}

以及以下Fluent映射:

public class ContainerMap: ClassMap<Container>
{
    public ContainerMap()
    {
        Table("Containers");
        Id(x => x.ContainerId);
        Map(x => x.Name);
        ReferencesAny(x => x.Location).IdentityType<Int64>().EntityTypeColumn("LocationType").EntityIdentifierColumn("LocationId")
            .AddMetaValue<UniqueLocation>("U")
            .AddMetaValue<SharedLocation>("S");
    }
}

public class LocationMap : ClassMap<Location>
{
    public LocationMap()
    {
        Table("Locations");
        Id(x => x.LocationId);
        Map(x => x.Name);
    }
}

public class UniqueLocationMap : SubclassMap<UniqueLocation>
{
    public UniqueLocationMap()
    {
        HasOne(x => x.Container).PropertyRef(x => x.Location).ForeignKey("LocationId").Cascade.All().Constrained();
    }
}

public class SharedLocationMap : SubclassMap<SharedLocation>
{
    public SharedLocationMap()
    {
        HasMany(x => x.Containers).KeyColumn("LocationId");
    }
}

问题是HasOne()映射生成以下异常:“破坏列映射:Container.Location:UniqueLocation,类型Object需要2列,但是1已映射”。

如何告诉HasOne()使用/映射LocationType和LocationId?

1 个答案:

答案 0 :(得分:0)

AFAIK除了使用公式之外,在实体引用上无法使用条件。设计似乎很奇怪,因为将一个独特的位置更改为共享位置会很糟糕。

您可以使用以下方式完成所需:

Reference(x => x.Container).Formula("(SELECT c.Id FROM Container c WHERE c.LocationId = Id AND c.LocationType = 'U')");

但我会优先

class Location
{
    ...
    public virtual bool IsUnique { get { return Container.Count == 1; } }
}