NHibernate如何将数据放入多对多映射中

时间:2014-11-26 09:55:56

标签: c# nhibernate fluent-nhibernate

这是我的两个班级。我做了映射和配置。 请指导我如何将数据放入其中。

class Actor
{
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
    public virtual IList <Movies> Movie{ get; set; }
}
class Movies
{
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
    public virtual IList <Actor> Actors{ get; set; }
}

1 个答案:

答案 0 :(得分:0)

我不确定你在这里问的是什么,但我会尽力回答我的想法。

为了使用Fluent NHibernate将多对多关系映射到数据库,问题中的类就像

一样简单
public class ActorMap : ClassMap<Actor>
{
    public ActorMap()
    {
        Id(x => x.Id);
        Map(x => x.Name);

        HasManyToMany(x => x.Movies)
            .Table("Actors_Movies")
            .ParentKeyColumn("ActorId")
            .ChildKeyColumn("MovieId")
            .LazyLoad()
            .Cascade.AllDeleteOrphan();
    }
}

public class MovieMap : ClassMap<Movie>
{
    public MovieMap()
    {
        Id(x => x.Id);
        Map(x => x.Name);

        HasManyToMany(x => x.Actors)
            .Table("Actors_Movies")
            .ParentKeyColumn("ActorId")
            .ChildKeyColumn("MovieId")
            .Inverse();
    }
}

数据库中的联结表对代码中的关系是透明的;认为这是将面向对象的代码映射到关系数据库的阻抗不匹配的工件

现在,如果您需要针对联结表存储其他数据,则需要在代码中公开代表联结表的类型,并为要存储的数据添加此类型的属性

public class MovieActorAssociation
{
    public MovieActorAssociation(Actor actor, Movie movie)
    {
        Actor = actor;
        Movie = movie;
    }

    protected MovieActorAssociation()
    {
    }

    public virtual Actor Actor { get; protected set; }

    public virtual int Id { get; protected set; }

    public virtual Movie Movie { get; protected set; }

    public virtual string SomeOtherProperty { get; set; }

    public static bool operator ==(MovieActorAssociation left, MovieActorAssociation right)
    {
        return Equals(left, right);
    }

    public static bool operator !=(MovieActorAssociation left, MovieActorAssociation right)
    {
        return !Equals(left, right);
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj))
        {
            return false;
        }
        if (ReferenceEquals(this, obj))
        {
            return true;
        }
        if (obj.GetType() != GetType())
        {
            return false;
        }
        return Equals((MovieActorAssociation)obj);
    }

    public override int GetHashCode()
    {
        return Id;
    }

    protected bool Equals(MovieActorAssociation other)
    {
        return Id == other.Id;
    }
}

现在,要映射关系

public class ActorMap : ClassMap<Actor>
{
    public ActorMap()
    {
        Id(x => x.Id).GeneratedBy.Identity();
        Map(x => x.Name);

        HasMany(x => x.MovieAssociations)
            .Cascade.AllDeleteOrphan()
            .Inverse()
            .KeyColumn("ActorId")
            .Not.KeyNullable();
    }
}

public class MovieActorAssociationMap : ClassMap<MovieActorAssociation>
{
    public MovieActorAssociationMap()
    {
        Id(x => x.Id).GeneratedBy.Identity();
        Map(x => x.SomeOtherProperty);

        References(x => x.Movie)
            .Not.Nullable()
            .Cascade.SaveUpdate()
            .Column("MovieId")
            .UniqueKey("Movie_Actor");

        References(x => x.Actor)
            .Not.Nullable()
            .Cascade.SaveUpdate()
            .Column("ActorId")
            .UniqueKey("Movie_Actor");
    }
}

public class MovieMap : ClassMap<Movie>
{
    public MovieMap()
    {
        Id(x => x.Id).GeneratedBy.Identity();
        Map(x => x.Name);

        HasMany(x => x.ActorAssociations)
            .Cascade.AllDeleteOrphan()
            .Inverse()
            .KeyColumn("MovieId")
            .Not.KeyNullable();
    }
}

并使用

var actor = new Actor { Name = "Actor Name" };
var movie = new Movie { Name = "Movie Name" };
var association = new MovieActorAssociation(actor, movie);

actor.MovieAssociations.Add(association);
movie.ActorAssociations.Add(association);

// some way of getting a Session
var session = SessionFactory.GetCurrentSession();

using (var transaction = session.BeginTransaction())
{     
    session.Save(actor);
    transaction.Commit();
}

您可能需要考虑公开添加和删除MovieActorAssociation类型的方法,以确保关联正确性,即添加到Actor上的属性集合的关联引用{ {1}}拥有集合的实例,而不是另一个actor实例。对于Actor类型,您也需要类似的逻辑。

相关问题