【问题标题】:Mapping a simple array映射一个简单的数组
【发布时间】:2011-05-27 14:55:09
【问题描述】:

我正在使用流利的 Nhibernate 来映射一个简单的类
并使用 Schema Generation 在 MySQL DB 上创建此类。
我不能将 IList 用于我的属性(我正在映射跨语言域类)
所以我必须使用简单的数组..

我希望 NHibernate 在两个类之间创建一个连接表,
这些是域类:

    public class ClassOne
    {
        public virtual Guid Guid { get; set; }
        public virtual String Title { get; set; }
        public virtual ClassTwo[] Tags { get; set; }
    }

    public class ClassTwo
    {
        public virtual Guid Guid { get; set; }
        public virtual string Title { get; set; }
    }

这是地图:

 public class ClassOneMap : ClassMap<ClassOneMap>
    {
        public ClassOneMap ()
        {
            Id(x => x.Guid).GeneratedBy.GuidComb();
            Map(x => x.Title);
            HasManyToMany(x => x.Tags)
                .Cascade.SaveUpdate());

        }
    }

    public class ClassTwoMap : ClassMap<ClassTwo>
    {
        public ClassTwoMap()
        {
            Id(x => x.Guid).GeneratedBy.GuidComb();
            Map(x => x.Title);
        }
    }

架构生成很棒!它有一个 ClassOne、ClassTwo 和 ClassTwoToClassOne 表 但是,当我尝试持久化 ClassOne 的实例时,我遇到了 Invalid Cast 异常。 这可以通过将数组更改为 IList 来解决,但我真的不能这样做..

谁能告诉我如何在不更改架构架构的情况下配置 Fluent 映射以使用数组?

非常感谢!

【问题讨论】:

  • 我很好奇,您使用的其他什么语言不允许 IList?

标签: c# mysql nhibernate fluent-nhibernate


【解决方案1】:

好的,玩过这个,希望能解决问题。

所以模型是:

 public class ClassOne : Entity
    {
        public virtual string Title { get; set; }

        public virtual ClassTwo[] Tags { get; set; }

     }

    public class ClassTwo : Entity
    {
        public virtual string Title { get; set; }
    }

基类包含在我的情况下很长的 Id 定义。应该不是Guids的问题

映射类:我们使用 FluentNhibernate 有一些约定,这个想法也在 HasManyToMany 中

public class ClassOneMappingOverride : IAutoMappingOverride<ClassOne>
    {
        public void Override(AutoMapping<ClassOne> mapping)
        {
            mapping.HasManyToMany(x => x.Tags).AsArray(x => x.Id).ParentKeyColumn("classOneId")
                .ChildKeyColumn("classTwoId")
                .Table("ClassOneLinkClassTwo")
                .Cascade.SaveUpdate();
        }
    }

请注意,如果您不指定ParentKey、ChildKey和Table,则不会创建链接表。

插入数据的单元测试如下:

 public class ClassOneDataPart : DataPartBase, IDataPart
{
    public void AddToDatabase()
    {
        var classOne = new ClassOne { Title = "classOne" };

        var classTwo1 = new ClassTwo { Title = "class21" };
        var classTwo2 = new ClassTwo { Title = "class22" };

        var tags = new[] { classTwo1, classTwo2 };

        classOne.Tags = tags;

        this.SaveData(classOne);
        this.SaveData(classTwo1);
        this.SaveData(classTwo2);
    }
}

输入数据库的结果是:

问候, 离子

【讨论】:

    【解决方案2】:

    将集合映射为私有字段并将其公开为数组。这也使得无需操作数组即可轻松公开 AddTag 和 RemoveTag 方法。

    public class ClassOne
    {
        private IList<ClassTwo> _tags;
    
        public virtual Guid Guid { get; set; }
        public virtual String Title { get; set; }
        public virtual ClassTwo[] Tags
        {
            // possibly expose as method to hint that the array is re-built on every call
            get { return _tags.ToArray(); }
        }
    }
    
    public class ClassOneMap : ClassMap<ClassOne>
    {
        public ClassOneMap ()
        {
            Id(x => x.Guid).GeneratedBy.GuidComb();
            Map(x => x.Title);
            HasManyToMany(x => x.Tags).Access.CamelCaseField(Prefix.Underscore)
                .Cascade.SaveUpdate());
    
        }
    }
    

    【讨论】:

      【解决方案3】:

      尝试使用 .AsArray(x=>x.Id)

      【讨论】:

      • 谢谢,但我已经尝试过了。模式生成器将 ManyToMany 表与 ClassTwo 表放在一起(它包含所有数据)。我真的不知道为什么......
      猜你喜欢
      • 2017-11-16
      • 2018-03-10
      • 1970-01-01
      • 1970-01-01
      • 2017-10-15
      • 1970-01-01
      • 2023-03-16
      • 2014-12-06
      • 1970-01-01
      相关资源
      最近更新 更多