2010-10-03 2 views
2

Я получаю SQL-запрос от NH и генерирует столбец, который не существует (таким образом, создается исключение ADO из NH).Fluent NHibernate + AutoMappings: Mystery Column in Generated SQL

SELECT roles0_.CreatedBy_id as CreatedBy4_1_, 
     roles0_.Id as Id1_, 
     roles0_.Id as Id18_0_, 
     roles0_.RoleDescription as RoleDesc2_18_0_, 
     roles0_.User_id as User3_18_0_ 
FROM [Role] roles0_ 
WHERE roles0_.CreatedBy_id=? 

Моя проблема в том, что я не могу понять, где CreatedBy колонна прибывает из. Вот моя структура классов.

public abstract class DomainEntity 
{ 
    public virtual int Id { get; set; } 
} 
public class User : DomainEntity 
{ 
    /* all the regular stuff you'd expect */ 
    public virtual IList<Role> Roles { get; private set; } 
} 
public class Role : DomainEntity 
{ 
    public virtual User User { get; set; } 
    public virtual string RoleDescription { get; set; } 
} 

При запуске приложения, я могу проверить конфигурацию, и я могу видеть ColumnIterator для класса Роль карты. Он содержит 4 элемента в словаре: id, user_id, roledescription и createdby_id. Таким образом, запрос является законным на основе конфигурации, но я не могу определить конфигурацию, основанную на классах.

Да, я очистил свой кеш-память ASP.NET, удалил каталоги bin и obj, и все остальное, что я мог придумать.

Редактировать # 1

Это мое Fluently.Configure заявление

_configuration = Fluently.Configure() 
    .Database(MsSqlConfiguration.MsSql2008.ConnectionString(_connectionString)) 
    .Mappings(m => m.AutoMappings.Add(GetPersistenceModel())) 
    .BuildConfiguration(); 

И это мой призыв к GetPersistenceModel()

private static AutoPersistenceModel GetPersistenceModel() 
{ 
    var configuration = new CustomAutomappingConfiguration(); 
    return AutoMap.AssemblyOf<User>(configuration) 
     .IgnoreBase(typeof(DomainEntity)) 
     .UseOverridesFromAssemblyOf<UserMapOverride>() 
     .Conventions.Setup(c => 
           { 
            c.Add<CustomHasManyConvention>(); 
           });    
} 

Мой заказ конфигурации говорит только карта общественного autoproperties , Это значит, что я могу добавить другие рассчитанные свойства для моих объектов домена. Переопределение карты пользователя гарантирует, что имя таблицы равно [User], потому что я получал SQL-ошибки, используя только User. Пользовательское соглашение HasMany устанавливает каскад all-delete-orphan для всех имеет много отношений.

Edit # 2

Это становится еще лучше. Это итератор столбца после создания объекта конфигурации, но перед созданием фабричного объекта сеанса.

before session factory

См? Нет столбца createdby_id в списке сопоставленных столбцов. Это итератор столбца после создания фабричного объекта сеанса.

after session factory

И теперь есть createdby_id колонка. Я действительно потерялся сейчас.

Редактировать 3

Хорошо, я думаю, что я на что-то прямо сейчас.

У меня появилось новое требование от моего клиента на прошлой неделе. Это требование заключалось в том, что они хотели знать, кто создал задание. Таким образом, он имеет новое свойство следующим образом.

public class Assignment : DomainEntity { 
    /* etc. */ 
    public virtual User CreatedBy { get; set; } 
    /* etc. */ 
} 

В таблице «Назначение» теперь есть столбец.

[CreatedBy_id] INT NULL 

И есть таблица FK для пользователя в этом новом столбце.

Если я прокомментирую эту недвижимость, все будет работать снова. SQL возвращается к запросам на user_id, точно так, как я ожидал. Есть ли какой-то тип переопределения, который я могу использовать, чтобы это не происходило?

+0

Вы используете AutoMapping или ClassMaps? Можете ли вы опубликовать свой вызов Fluently.Configure? – Yogesh

+0

Можете ли вы показать нам свои * полные * сущности? Суффикс '_id 'указывает, что это отношение внешнего ключа, которое было сопоставлено, поэтому в вашем домене должно быть свойство или класс' CreatedBy'; automapper работает, отражая свойства и классы в ваших сборках, он не может ничего сделать. –

+1

И, пожалуйста, напишите свой 'CustomHasManyConvention' и' UserMapOverride'. – Yogesh

ответ

1

Ну, у меня есть решение, но я не знаю, является ли это лучшим ответом, или если есть еще лучшее решение.

я могу добавить следующее к моему UserMapOverride классу

public class UserMapOverride : IAutoMappingOverride<User> { 
    public void Override(Automapping<User> mapping) { 
    // Ensure that the string "User" is properly SQL-escaped. Without this line, 
    // SQL queries are breaking. 
    mapping.Table("[User]"); 

    // Force the FK to use the correct column. 
    mapping.HasMany(x => x.Roles).KeyColumn("User_id"); 
    } 
} 

Я надеюсь, что кто-нибудь сказать мне, что я делаю что-то не так с моим Автоотображением, и мне не нужен, чтобы начать бросать в переопределение.

Смежные вопросы