Свободная коллекция Nhibernate ManyToMany - не спасающие ассоциации - PullRequest
4 голосов
/ 30 марта 2010

Я не могу понять, почему это не работает ..

У меня есть относительно чистая модель сущностей, состоящая из POCO, созданных с учетом DDD (хотя, вероятно, не соблюдающих большинство правил даже свободно).

Я использую Fluent NHibernate для отображения. Я также использую SchemaExport для создания схемы базы данных, с минимальным вкладом от меня, как это сделать. NHibernate волен выбирать лучший способ.

У меня есть две сущности с отношениями «многие ко многим» друг с другом (удален неинтересный код); MediaItem и Tag; MediaItems может иметь много тегов, теги могут быть применены ко многим MediaItems, и я хочу, чтобы коллекции были на обеих сторонах, чтобы я мог легко разбираться с вещами.

(немного проблем с форматированием ниже, извините)

  • Tag:

    тег публичного класса {

    private IList<MediaItem> _mediaItems;
    public virtual long Id { get; set; }
    public virtual string TagName { get; set; }
    public virtual IEnumerable<MediaItem> MediaItems { get { return _mediaItems; } }
    
    public Tag()
    {
        _mediaItems = new List<MediaItem>();
    }
    
    protected internal virtual void AddMediaItem(MediaItem newItem)
    {
        _mediaItems.Add(newItem);
    }
    

    }

Я пытался быть умным, выставляя коллекции только как IEnumerable и разрешая добавлять элементы только через методы. Я также слышал, что только одна сторона отношений должна отвечать за это - таким образом, надуманный AddMediaItem () на Tag.

MediaItemMap выглядит так:

public class MediaItemMap : ClassMap<MediaItem>
{
    public MediaItemMap()
    {
        Table("MediaItem");

        Id(mi => mi.Id);

        Map(mi => mi.Title);

        HasManyToMany<Tag>(mi => mi.Tags)
            .Access.CamelCaseField(Prefix.Underscore)
            .Cascade.SaveUpdate();
    }
}

Отображение тегов выглядит следующим образом:

public class TagMap : ClassMap<Tag>
{
    public TagMap()
    {
        Table("Tag");

        Id(t => t.Id);

        Map(t => t.TagName);

        HasManyToMany<MediaItem>(mi => mi.MediaItems)
            .Access.CamelCaseField(Prefix.Underscore)
            .Inverse();
    }
}

Теперь у меня есть некоторый тестовый код, который отбрасывает схему базы данных, воссоздает ее (так как я здесь отлаживаю мозги), а затем запускает следующий простой код:

Tag t = new Tag { TagName = "TestTag" };
MediaItem mi = new MediaItem { Title = "TestMediaItem" };

mi.AddTag(t);

var session = _sessionFactory.OpenSession();

session.Save(mi);

Да, это тестовый код, в этом посте он никогда не пройдет.

MediaItem сохраняется, как и тег. Однако ассоциации между ними нет. NHibernate создает таблицу ассоциации "MediaItemsToTags", но не пытается вставить в нее что-либо.

При создании ISessionFactory я указываю ShowSQL () - чтобы я мог видеть все DDL, отправленные на сервер SQL. Я вижу оператор вставки для таблиц MediaItem и Tag, но вставка для MediaItemsToTags отсутствует.

Я экспериментировал со многими различными версиями этого, но я не могу его взломать. Каскадирование - одна из возможных проблем, я пробовал использовать Cascade.All () с обеих сторон, Inverse () с обеих сторон и т. Д., Но без кубиков.

Может кто-нибудь сказать мне, как правильно сопоставить это, чтобы NHibernate фактически сохранял ассоциацию всякий раз, когда я сохраняю свой MediaItem?

Спасибо!

1 Ответ

2 голосов
/ 31 марта 2010

Вам нужно определить столбцы «многие ко многим», столбцы родительских и дочерних ключей:

public class MediaItemMap : ClassMap<MediaItem>
{
    public MediaItemMap()
    {
        Table("MediaItem");

        Id(mi => mi.Id);

        Map(mi => mi.Title);

        HasManyToMany<Tag>(mi => mi.Tags)
            .Table("MediaItemsToTags").ParentKeyColumn("Id").ChildKeyColumn("Id")
            .Access.CamelCaseField(Prefix.Underscore)
            .Cascade.SaveUpdate();
    }
}

Синтаксис в TagMap идентичен, поскольку оба ключевых столбца названы "Id".

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...