3

I'm using fluent Nhibernate to map a simple class
And using Schema Generation to create this class on MySQL DB.
I can't use IList<> for my properties (I'm mapping cross-language domain classes)
So I have to use simple arrays..

I Want NHibernate to create a connection table between the two classes,
These are the domain classes:

    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; }
    }

And this is the map:

 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);
        }
    }

The schema generates great! It has a ClassOne, ClassTwo and ClassTwoToClassOne Tables But when I'm trying to persist an instance of ClassOne I have an Invalid Cast exception.. This is solved by changing the arrays to IList's but I can't really do that..

Can anyone tell me how to configure the Fluent mapping to use Arrays without changing the schema architecture?

Thanks A'lot!

1
  • I'm curious, what other language are you using that doesn't allow IList? Commented Dec 18, 2010 at 19:11

3 Answers 3

2

Ok, played around this and hope that solve the question.

So models are:

 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; }
    }

Base class contains the Id definition which is long in my case. Should not be a problem with Guids

Mapping class: We are using FluentNhibernate with some convention, also the idea is in 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();
        }
    }

Please note that if you not indicate ParentKey, ChildKey and Table it will not create the link table.

The unit test which insert data looks like:

 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);
    }
}

and the result into database is:

alt text

Regards, Ion

Sign up to request clarification or add additional context in comments.

Comments

1

Map the collection as a private field and expose it as an array. This also makes it easy to expose AddTag and RemoveTag methods without manipulating the array.

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());

    }
}

Comments

0

Try to use .AsArray(x=>x.Id)

1 Comment

Thanks but I Have already tried that.. The schema generator puts the ManyToMany table with the ClassTwo table (It holds all the data).. I Can't really figure out why..

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.