Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
403 views
in Technique[技术] by (71.8m points)

c# - How to create NHibernate HasManyToMany relation

I know there are questions about HasManyToMany but this time I want to put couple fields into middle table like 'Description, CreationDate'.

For my situation I don't want to bind two way. I have company, person and address tables. And every company or person may have more than 1 address. In this situation what should I do? How should I write the code of classes and mappings?

Below you can see the tables:

enter image description here

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

In this case the answer is pretty simple. Do not use many-to-many. Use pairing object. Exactly for the reasons you've mentioned: Extend the pairing object with more properties:

Check here 24. Best Practices, a cite:

Don't use exotic association mappings.

Good usecases for a real many-to-many associations are rare. Most of the time you need additional information stored in the "link table". In this case, it is much better to use two one-to-many associations to an intermediate link class. In fact, we think that most associations are one-to-many and many-to-one, you should be careful when using any other association style and ask yourself if it is really neccessary.

Other words, create the one-to-many relations refering the pairing objects from boht ends, and many-to-one from the pairing object.

Also check these:

An example of the Address and Company. First Pairing object

public class AddressCompany
{
    // the relation to both sides
    public virtual Address Address { get; set; }
    public virtual Company Company { get; set; }

    // many other settings we need
    public virtual string   Description  { get; set; }
    public virtual DateTime CreationDate { get; set; }
    ...
}

the Address and Company in a nut-shell:

public class Address
{
    public virtual IList<AddressCompany> Companies { get; set; }
    ...
}

public class Company
{
    public virtual IList<AddressCompany> Addresses { get; set; }
    ...
}

The mapping is as expected:

public AddressMap()
{
    HasMany(x => x.Companies)
     ...
}
public CompanyMap()
{
    HasMany(x => x.Addresses)
     ...
}
public AddressCompanyMap()
{
    References(x => x.Address)..
    References(x => x.Company)..
     ...
}

So, this is representing the Pairing object

Well, but now we can find some Companies Created after a date:

var subquery = QueryOver.Of<AddressCompany>()
    .Where(c => c.CreationDate > new DateTime(2000, 1, 1))
    .Select(c => c.Company.ID);

var query = session.QueryOver<Company>()
    .WithSubquery
    .WhereProperty(c => c.ID)
    .In(subquery)
    ...;

This way we can also filter Company over the Address...


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...