Свободная вставка больших объемов данных NHibernate

1

Мне нужно перенести некоторые данные в другие db, но когда я запустил это замораживание сервера mssql. Число строк ds2 составляет около 250 000. Что я делаю не так?

каждый раз, когда я пытаюсь использовать тот же funcion, сначала выглядит работающим, а после ошибки - случайной строкой. возможно, 5, 95 или 280. до тех пор, пока записи ошибок не будут действительны.

        string inlineSql = "Select * from album";
        DataSet ds2 = SqlHelper.ExecuteDataset(ConnectionString, CommandType.Text, inlineSql);

        for (int i = 0; i < ds2.Tables[0].Rows.Count; i++)
        {
            Entity.Album.Album album = new Entity.Album.Album();
            album.AlbumName = ds2.Tables[0].Rows[i]["AlbumName"].ToString();
            album.WebSite = (Entity.Artist.WebSite)Convert.ToInt16(ds2.Tables[0].Rows[i]["WebSite"]);
            album.Year = ds2.Tables[0].Rows[i]["Year"].ToString();

            Entity.Artist.Artist artist = Entity.Artist.Artist.READ.ById(Convert.ToInt32(ds2.Tables[0].Rows[i]["ArtistId"]));
            if (artist != null)
            {
                artist.AddAlbum(album);
                album.Save();
            }
        }

Метод AddAlbum

    public virtual void AddAlbum(Album.Album album)
    {
        album.Artist = this;
        AlbumList.Add(album);
    }

Метод сохранения

    using (var session = NHibernateHelper.OpenSession())
    {
        using (var transaction = session.BeginTransaction())
        {
            session.SaveOrUpdate(x);

            transaction.Commit();
        }
    }

Ошибка в session.SaveOrUpdate(x);

Ошибка:

Исключение типа "NHibernate.Exceptions.GenericADOException" произошло в NHibernate.dll, но не было обработано в коде пользователя

Дополнительная информация: не удалось вставить: [Entity.Album.Album] [SQL: INSERT INTO [Album]

(AlbumName, WebSite, Year, ArtistId) VALUES (?,?,?,?); выберите SCOPE_IDENTITY()]

AlbumMap

public class AlbumMap : ClassMap<Album>
{
    public AlbumMap()
    {
        Id(x => x.AlbumId);
        Map(x => x.AlbumName);
        Map(x => x.WebSite).CustomType<short>();
        Map(x => x.Year);
        HasMany(x => x.LyricList).Table("Lyric").KeyColumn("AlbumId").Cascade.All().Not.LazyLoad();
        References(x => x.Artist).Column("ArtistId").ForeignKey("ArtistId").Fetch.Join();
    }

}

ArtistMap

public class ArtistMap : ClassMap<Artist>
{
    public ArtistMap()
    {
        Id(x => x.ArtistId);
        Map(x => x.ArtistName);
        Map(x => x.ArtistURL);
        Map(x => x.ImgName);
        Map(x => x.ImgURL);
        Map(x => x.Alfabet);
        Map(x => x.SeoLink);
        Map(x => x.WebSite).CustomType<short>();
        HasMany(x => x.AlbumList).Table("Album").KeyColumn("ArtistId").Cascade.All().Not.LazyLoad();
    }

}

Больше исключений

Оператор INSERT противоречил ограничениям FOREIGN KEY "FKA0CE20AA48AC4CAD". Конфликт произошел в базе данных "LYRICSWEB", таблице "dbo.Artist", в столбце "ArtistId". Заявление было прекращено.

  • 0
    Не могли бы вы добавить следующие строки этого исключения, пожалуйста? точно будет интересная информация ... СОВЕТ: то, что мы видим сейчас, похоже, что столбец albumId не включил идентичность ...
  • 0
    это все исключение. Спецификация идентичности AlbumId ДА также я добавляю ClassMap
Показать ещё 2 комментария
Теги:
sql-server
nhibernate
fluent-nhibernate

1 ответ

2
Лучший ответ

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

Дополнительная информация: не удалось вставить: [Entity.Album.Album] [SQL: INSERT INTO [Album]
(AlbumName, WebSite, Year, ArtistId) VALUES (?,?,?,?); выберите SCOPE_IDENTITY()]

в то время как мы грузим художник правильным способом...

Entity.Artist.Artist artist = Entity.Artist.Artist.READ
  .ById(Convert.ToInt32(ds2.Tables[0].Rows[i]["ArtistId"]));

Проблема заключается в неправильном сопоставлении коллекции. Ссылка от альбома к художнику кажется правильной:

public AlbumMap()
{
    ..
    References(x => x.Artist)
       .Column("ArtistId")
       .ForeignKey("ArtistId")
       .Fetch.Join();
}

Но другой конец этого отношения отображается следующим образом:

// wrong
public ArtistMap()
{
    ..
    HasMany(x => x.AlbumList)
       .Table("Album")
       .KeyColumn("AlbumId")         // wrong
       .Cascade.All().Not.LazyLoad();
}

Оба эти отношения одинаковы ! Они отображаются только с разных концов (с точки зрения коллекции и от предполагаемого владельца коллекции).

Это означает, что столбец отображения должен быть одним и тем же, то есть не "AlbumId" а "ArtistId"

// correct
public ArtistMap()
{
    ..
    HasMany(x => x.AlbumList)
       .Table("Album")
       .KeyColumn("ArtistId")         // this is the relation
       .Cascade.All().Not.LazyLoad();
}

Поскольку NHibernate загружает некоторого исполнителя и его коллекцию AlubmList.., это может привести к некоторым неожиданным заявлениям вставки... исправление этого сопоставления должно помочь...

Второе, что нужно отметить: Inverse()

Мы работаем с экземплярами Album... и мы назначаем их отношение к обладателю коллекции - Artist. Это хорошо и предлагается, как это сделать. Хорошо.

Но мы можем извлечь выгоду из функции NHibernate под названием Inverse(), которая уменьшит количество операторов SQL... и сделает все вложение более простым... поэтому расширьте сопоставление с Artist следующим образом:

// correct
public ArtistMap()
{
    ..
    HasMany(x => x.AlbumList)
       .Table("Album")
       .KeyColumn("ArtistId")  // this is the relation
       .Cascade.All()
       .Not.LazyLoad()
       .Inverse();             // ESSENTIAL improvement of generated SQL
}

Проверьте это для более подробной информации.

  • 0
    Вы были правы по поводу ArtistId, который я исправил, который также пытался использовать Inverse, но ни один из них не исправил ошибку. Эта информация может помочь, каждый раз, когда я пробую ту же функцию, сначала выглядит работающей, а после выдает ошибку в случайной строке. может быть 5, 95 или 280. пока записи об ошибках не станут действительными.
  • 0
    Такая информация не помогает; (... случайные проблемы ... непредсказуемые ... я могу помочь с обнаруженной проблемой ... если вы понимаете, о чем я ... попробуйте, пожалуйста, найти более подробную информацию ... и опять же, стек исключений (если это новое исключение, еще лучше, возможно, выдать новый вопрос, только если исключение совершенно другое), НО, если исключение остается тем же - попробуйте сравнить все значения в ArtistId FROM table / db. .. если они существуют в таблице TARGET / db
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню