流畅的NHibernate批量数据插入

时间:2014-07-27 13:25:04

标签: c# sql-server nhibernate fluent-nhibernate

我需要将一些数据传输到其他数据库,但是当我启动这个mssql服务器冻结时。 ds2行数约为250,000。我做错了什么?

每次我尝试相同的功能时,首先看起来工作,然后在随机行上给出错误。可能是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:   插入[专辑]

     

(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'。声明一直如此   终止。

1 个答案:

答案 0 :(得分:2)

有一些迹象,应该导致答案。我们可以看到错误是:

  

附加信息:无法插入:[Entity.Album.Album] [SQL:INSERT INTO [相册]
  (AlbumName,WebSite,Year,ArtistId)VALUES(?,?,?,?);选择SCOPE_IDENTITY()]

虽然我们正在装载艺术家正确的方式...

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

问题在于错误的集合映射。从Albumt到Artist的引用似乎是正确的:

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。这是好的,并建议如何做到这一点。好。

但是我们可以从名为Inverse()的NHibernate功能中获益,这将减少一些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
}

查看this了解详情