Отображение идентификатора объекта как идентификатора - PullRequest
2 голосов
/ 09 марта 2012

У меня есть объекты домена в FluentNHibernate, у которых есть идентификаторы типа object, которые всегда будут int (рассуждая ниже).Прямо сейчас у меня есть серверная часть SQLite.Я хочу отобразить Id как автоинкремент.Пока у меня есть:

public class UserMap : ClassMap<User>
{
    public UserMap()
    {
        Table("Users");
        Id(x => x.Id).CustomType<int>().GeneratedBy.Native();
        Map(x => x.Email);
    }
}

public class User
{
    public virtual object Id { get; set; }
    public virtual string Email { get; set; }
}

Но когда загружаются карты, он выбрасывает FluentConfigurationException с сообщением Identity type must be integral (int, long, uint, ulong) для свойства User.Id (трассировка стека говорит, что это происходит, когда я вызываю Native. Опять же, я просто хочу получить целое число с автоинкрементом.

Обоснование для идентификатора объекта

У нас есть бизнес-требование для поддержки нескольких СУБД, а также MongoDB.Я уже хорошо осознаю, что это плохая идея, поэтому, пожалуйста, просто сконцентрируйтесь на этом вопросе. Mongo использует ObjectId (похожий на Guid несколько последовательный тип значения) для своего типа идентификатора по умолчанию. Идея состоит в том, чтобы скрыть фактический тип идентификатора (потому чтоэто зависит от уровня данных), но повторно использовать модели и иметь две разные реализации доступа к данным (Mongo и NHibernate).

Ответы [ 3 ]

3 голосов
/ 09 марта 2012

Я решил эту проблему, выполнив

Id(x => x.Id).CustomType<int>()
    .GeneratedBy.Custom<global::NHibernate.Id.IdentityGenerator>()
    .UnsavedValue(null);

По какой-то причине беглый NHibernate не понимает, что .CustomType<int>() означает, что он действительно int Поэтому мне пришлось добавить собственный генератор, чтобы обойти логику Fluent.

Это решает непосредственную проблему, но мне все еще нужно выяснить, как должны работать коллекции и внешние ключи.

1 голос
/ 09 марта 2012

Здесь все вместе.

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

public interface IUser
{
    dynamic Id {get;set;}
    string Email {get;set;}
}

public class MongoUser : IUser{...}

public class SqlUser : IUser {...}

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

0 голосов
/ 09 марта 2012

Вместо CustomType<int>, попробуйте CustomType<NHibernate.Type.Int32Type>

Если это не сработает, вы можете просто удалить свойство Id и отобразить его только в NHibernate.У этого есть несколько проблем программирования (по сути, вы должны вызвать NHibernate, чтобы получить идентификатор сущности), но это будет работать.

Я не уверен, поддерживает ли Fluent это;Я уверен, что XML делает и почти уверен, что MappingByCode тоже.

...