帮助流畅的NHibernate映射通用类

时间:2010-06-11 16:03:59

标签: generics fluent-nhibernate

我希望有人可以帮我这个,我正在尝试为一个被子类化为泛型类的类编写映射类。它更容易用代码描述,所以这是我的模型......

public abstract class TagBase
{
    public virtual int Id { get; private set; }
    public virtual TagTypeEnum TagType { get; set; }
    public virtual string Value { get; set; }
    public virtual bool IsSystemTag { get; private set; }
    public virtual bool isDeleted { get; set; }

    public TagBase()
    {
    }

    public TagBase(TagTypeEnum tagType)
    {
        this.TagType = tagType;
    }

    public override string ToString()
    {
        return Value;
    }
}

public class Tag<TLinkedItem> : TagBase where TLinkedItem : ITagged<TLinkedItem>
{
    public virtual List<TLinkedItem> LinkedItems { get; set; }
}

正如您所看到的,Tag是通用的,但仅限于那些实现ITagged<T>

的类

这个想法是一个实体有标签,反过来一个标签有一个强类型的LinkedItem列表。

标签不能在不同类型的实体之间共享

我的模型中只有两个支持标记的实体到目前为止DisplayAsset

我尝试使用以下Fluent NHibernate代码映射它;

public class TagBaseMap : ClassMap<TagBase>
{
    public TagBaseMap()
    {
        Table("Tag");
        Id(tag => tag.Id);
        Map(tag => tag.Value).Not.Nullable().Length(50);
        Map(tag => tag.IsSystemTag).Not.Nullable();
        Map(tag => tag.isDeleted).Not.Nullable();
        Map(tag => tag.TagType).CustomType<Int32>().Not.Nullable();
    }
}

public class DisplayTagMap : SubclassMap<Tag<Display>>
{
    public DisplayTagMap()
    {
        HasManyToMany(displayTag => displayTag.LinkedItems).Inverse().Table("DisplayTagLink");
    }
}

public class AssetTagMap : SubclassMap<Tag<Asset>>
{
    public AssetTagMap()
    {
        HasManyToMany(assetTag => assetTag.LinkedItems).Inverse().Table("AssetTagLink");
    }
}

当我尝试构建数据库时,我的目标是Sql Server,从这个映射我得到这个错误“'''附近的语法不正确。”

我是否正确思考.Net的泛型类命名,即

'{[ Model.Tag'1 [[Model.Asset,Model,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null]]。LinkedItems,NHibernate.Mapping.Bag( Model.Tag'1 [[Model.Asset,Saturn.ConnectVision.Model,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null]]。LinkedItems)]}'

我在这里做些蠢事吗?

有解决这个问题的方法吗?

提前感谢任何建议。

1 个答案:

答案 0 :(得分:1)

好的,我似乎暂时解决了这个问题。

以下是Tag的通用版本的映射,其中T:ITagged

public class DisplayTagMap : SubclassMap<Tag<Display>>
{
    public DisplayTagMap()
    {
       HasManyToMany(displayTag => displayTag.LinkedItems).Inverse().Table("DisplayTagLink").ParentKeyColumn("display_id").ChildKeyColumn("tag_id");
    }
}

public class AssetTagMap : SubclassMap<Tag<Asset>>
{
    public AssetTagMap()
    {
        HasManyToMany(assetTag => assetTag.LinkedItems).Inverse().Table("AssetTagLink").ParentKeyColumn("asset_id").ChildKeyColumn("tag_id");
    }
}

所以我重写了导致非法Sql语法的生成列名,当然还有需要考虑的反向映射。

    public class DisplayMap : ClassMap<Display>
{
    public DisplayMap()
    {
        Id(display => display.Id);
        Map(display => display.Name).Not.Nullable();
        Map(display => display.DisplayGUID).Not.Nullable();
        Map(display => display.Description);
        HasManyToMany(display => display.Tags).Cascade.All().Table("DisplayTagLink").ParentKeyColumn("display_id").ChildKeyColumn("tag_id");
    }
}

我现在唯一的问题是,如果我输入DiscriminateSubclassesOnColumn("TagType"),我会遇到相同的语法问题。

如果我错过了这个声明,我最终会得到两个额外的表,Tag_Asset和Tag_Display只包含一个返回Tag的外键。现在这不是什么大问题。

我避免使用DiscriminateSubClassOnColumn("TagType").SubClass<Tag<Display>>(.....,因为这会导致我必须为我添加的每个子类修改此声明。