FluentNHibernate: Как перевести HasMany (x => x.Addresses) .KeyColumn ("PersonId") в автоматическое отображение - PullRequest
1 голос
/ 23 мая 2011

Допустим, у меня есть следующие модели:

public class Person
{
    public virtual int Id { get; private set; }
    public virtual ICollection<Address> Addresses { get; private set; }
}

public class Address
{
    public virtual int Id { get; private set; }
    public virtual Person Person { get; set; }
}

Я хочу, чтобы FluentNHibernate создал следующие таблицы:

Person
    PersonId
Address
    AddressId
    PersonId

Этого можно легко добиться с помощью отображения на основе флюента:

public class PersonMapping : ClassMap<Person>
{
    public PersonMapping()
    {
        Id(x => x.Id).Column("PersonId");
        HasMany(x => x.Addresses).KeyColumn("PersonId");
    }
}

public class AddressMapping : ClassMap<Address>
{
    public AddressMapping()
    {
        Id(x => x.Id).Column("AddressId");
        References(x => x.Person).Column("PersonId");
    }
}

Я хочу получить тот же результат, используя автоматическое сопоставление.Я попробовал следующие соглашения:

class PrimaryKeyNameConvention : IIdConvention
{
    public void Apply(IIdentityInstance instance)
    {
        instance.Column(instance.EntityType.Name + "Id");
    }
}

class ReferenceNameConvention : IReferenceConvention
{
    public void Apply(IManyToOneInstance instance)
    {
        instance.Column(string.Format("{0}Id", instance.Name));
    }
}

Но я с сожалением обнаружил, что он создал следующие таблицы:

Person
    PersonId
Address
    AddressId
    PersonId
    Person_id // this column should not exist

Ниже приведена остальная часть моего кода:

ISessionFactory sessionFactory = Fluently.Configure()
    .Database(MsSqlConfiguration.MsSql2008.ConnectionString(connectionString))
    .Mappings(m =>
                m.AutoMappings.Add(AutoMap.Assemblies(typeof(Person).Assembly)
                    .Conventions.Add(typeof(PrimaryKeyNameConvention))
                    .Conventions.Add(typeof(ReferenceNameConvention)))

                //m.FluentMappings
                //    .Add(typeof (PersonMapping))
                //    .Add(typeof (AddressMapping))
    )
    .ExposeConfiguration(BuildSchema)
    .BuildConfiguration()
    .BuildSessionFactory();

Есть идеи?Спасибо.

1 Ответ

5 голосов
/ 23 мая 2011

Требуется соглашение о внешнем ключе:

public class SimpleForeignKeyConvention : ForeignKeyConvention
    {
        protected override string GetKeyName(Member property, Type type)
        {
            if(property == null)
                return type.Name + "Id";
            return property.Name + "Id";
        }
    }

Кроме того, ваше условное обозначение должно выглядеть примерно так:

instance.Column(instance.Property.Name + "Id");
...