流畅的NHibernate批量数据插入
本文关键字:数据 插入 NHibernate | 更新日期: 2023-09-27 18:15:10
我需要传输一些数据到其他数据库,但是当我启动这个mssql服务器冻结。Ds2行数约为25万。我做错了什么?
每次我尝试相同的函数首先看起来工作,然后在随机行上给出错误。也许是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中,但未在用户代码中处理
附加信息:could not insert: [Entity.Album.Album][SQL:INSERT INTO[相册]
(专辑名称,网站,年份,艺人)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表"。艺术家",列"ArtistId"。声明是终止。
有一些迹象,应该会导致答案。我们可以看到错误是:
附加信息:could not insert: [Entity.Album.][SQL: INSERT INTO[相册]
(专辑名称、网址、年份、艺人), ?, ?, ?);选择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
实例…并将它们的关系赋值给collection holder - Artist
。这是一个很好的建议方法。好。
但是我们可以从NHibernate的逆()特性中获益,它将减少一些SQL语句…并使所有的插入更简单…所以像这样扩展你的艺术家映射:
// 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
}
查看更多详细信息