我使用NHibernate和FluentNHibernate作为我的DAL.我也在使用SchemaExport和SchemaUpdate创建和更新我的数据库模式.
我的问题是模式操作都需要数据库存在才能工作.我想以编程方式创建我的数据库并更新模式,因为可能有多个数据库,并且创建数据库不仅是一次性操作.
我知道我可以通过在与master数据库的连接上执行create database命令来手动执行此操作,但考虑到我否则使用NHibernate进行所有数据库交互,这感觉不对.顺便说一句,我使用SQLite内存数据库进行单元测试,因此我编写的任何sql都必须知道我正在使用哪个数据库.
有没有办法让NHibernate为我创建我的数据库?
我的数据库架构有一个字符串作为varchar(max).我已经阅读了有关将Length设置为4000或8000以上的其他问题,以便它在映射中真正生成(n)varchar(max)但是当我在映射类中使用Length(10000)时,hbm文件实际上显示了长度="10000"如果我保存一个超过10000个字符的实体,它实际上被截断为10000个字符.
我不想要任何截断.
(使用NH3-alpha2和FNH主干)
我正在尝试建立如下关系.每个主项目都有一个或多个详细信息项:
public class Detail {
public virtual Guid DetailId { get; set; }
public virtual string Name { get; set; }
}
public class Master {
public virtual Guid MasterId { get; set; }
public virtual string Name { get; set; }
public virtual IList<Detail> Details { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
和映射:
public class MasterMap : ClassMap<Master>
{
public MasterMap()
{
Id(x => x.MasterId);
Map(x => x.Name);
HasMany(x => x.Details).Not.KeyNullable.Cascade.All();
}
}
public class DetailMap : …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用流畅的NHibernate将大量对象插入到表中,使用调用来保存或更新在foreach循环中从集合中传递每个实体.我已经将批量大小设置为集合的大小,但是我已经在Ayende的博客上看到,不建议将其设置为大值,所以我将其限制为250,但是当我在NHProf中查看集合时,我查看插入语句流(该集合大约是20000个项目),而不是一组批量插入调用.
这似乎非常低效,并且花费的时间比我期望的查询本质上非常基本 - 将值插入25列(是的,这是一个可以做得更好的地方,但它是遗留数据库)我现在仍然坚持到SQL Server 2008数据库 - 所以我只能假设我做错了.
是否有推荐的方法使用NHibernate插入大型实体集合?使用Save over SaveOrUpdate可以提高效率吗?
add方法的代码 - SetBatchSize调用是批处理上限为250的位置,或者如果小于250则设置为集合大小:
public void Add(IEnumerable<TEntity> entities)
{
var session = GetCurrentSession();
using (var transaction = session.BeginTransaction())
{
entities = entities.ToList();
session.SetBatchSize(SetBatchSize(entities.Count()));
foreach (var entity in entities)
session.SaveOrUpdate(entity);
transaction.Commit();
}
}
Run Code Online (Sandbox Code Playgroud)
对于稍微模糊的问题道歉,我感觉我只是以错误的方式接近事情而且任何指针都会非常感激!
我对NHibernate非常陌生,所以如果我在这里遗漏了一些微不足道的话我会道歉.我目前正在编写一本名为"NHibernate 3初学者指南"的书,来自packtpub.我大多数都遵循书中的指示.当我说大多数情况下我使用MySQL而不是MSSQL而已经分歧并且一直在使用NuGet而不是手动下载二进制文件.
我现在在第2章,这是第一个真正的编码章节.在本章中,我将构建一个简单的WPF应用程序,通过单击按钮来构建我的数据库模式.我已经为本章中指定的类Product和Category类构建了一些POCO .通过NuGet,我添加了以下参考:
当我单击按钮来构建我的数据库时,执行以下代码块:
private const string connString = "string omitted for brevity";
private void btnCreateDatabase_Click(object sender, RoutedEventArgs e)
{
Fluently.Configure().Database(MySQLConfiguration.Standard.ConnectionString(connString))
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<ProductMap>())
.ExposeConfiguration(CreateSchema)
.BuildConfiguration();
}
Run Code Online (Sandbox Code Playgroud)
单击按钮后,我收到以下异常(FileLoadException):
外部异常消息: Could not load file or assembly 'Iesi.Collections, Version=4.0.0.0, Culture=neutral, PublicKeyToken=aa95f207798dfdb4' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
内部例外消息: Could not load file or assembly 'Iesi.Collections, Version=1.0.1.0, Culture=neutral, PublicKeyToken=aa95f207798dfdb4' …
我想映射一个导致左外连接而不是内在连接的类.
我的复合用户实体由一个表("aspnet_users")和第二个表中的一些可选属性(如"users"中的FullName)组成.
public class UserMap : ClassMap<User> {
public UserMap() {
Table("aspnet_Users");
Id(x => x.Id, "UserId").GeneratedBy.Guid();
Map(x => x.UserName, "UserName");
Map(x => x.LoweredUserName, "LoweredUserName");
Join("Users",mm=>
{
mm.Map(xx => xx.FullName);
});
}
}
Run Code Online (Sandbox Code Playgroud)
这个映射结果在内连接选择中,所以没有结果出来是第二个表没有数据.我想生成一个左连接.
这只能在查询级别进行吗?
我想添加一个事件监听器(IPreUpdateEventListener)来添加NHibernate但是在使用流畅的配置时我似乎无法找到一个例子.
我希望能够在创建会话工厂时添加侦听器,例如,当执行以下代码时.
_sessionFactory = Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2005.ConnectionString(connectionString).ShowSql())
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<IEntity>())
.BuildSessionFactory();
Run Code Online (Sandbox Code Playgroud)
有人知道怎么做吗?
如何在MappingIntegrationTests中作为测试的一部分生成xml映射文件
我需要手动检查流畅的映射是否与leagcy项目中的映射关联.
nhibernate nhibernate-mapping fluent-nhibernate s#arp-architecture
我刚刚更新了我的项目以使用NuGet进行外部引用.我添加了对NHibernate的引用,它添加了NH的所有其他依赖项.比我添加了FluentNHibernate.为NH和Fluent下载的NH版本不匹配.NuGet显示FNH的版本为1.1.1.694,依赖于NH版本3.0.0.0.2001,而NH显示为版本3.0.0.4000.
当我运行应用程序时,我收到此消息:
无法加载文件或程序集'NHibernate,Version = 3.0.0.2001,Culture = neutral,PublicKeyToken = aa95f207798dfdb4'或其依赖项之一.定位的程序集的清单定义与程序集引用不匹配.(HRESULT异常:0x80131040)
我也尝试从FNH网站下载,但这表明FNH上的版本是1.1.0.685,这取决于2.1.2.4000.
你能修复NuGet,还是应该在配置中使用BindingRedirect?
我正在尝试使用Fluent NHibernate来迁移需要某些数据库"按摩"的数据库.源数据库是MS Access数据库,我粘贴的当前表是一个带有OLE对象字段的表.目标数据库是MS SQL Server Express数据库.
在实体中我简单地将此字段定义为a byte[]但是在加载时,即使只是为单个记录加载该单个字段,我也遇到了System.OutOfMemoryException
byte[] test = aSession.Query<Entities.Access.Revision>().Where(x => x.Id == 5590).Select(x => x.FileData).SingleOrDefault<byte[]>();
Run Code Online (Sandbox Code Playgroud)
然后我尝试实现此处列出的blob类型,但现在运行时我收到错误:
"无法将'System.Byte []'类型的对象强制转换为'TestProg.DatabaseConverter.Entities.Blob'."}
我无法想象Ole对象是否大于100mb但无法检查.有没有什么好的方法可以使用Fluent NHibernate从一个数据库中复制出来并将其保存到另一个数据库中,还是需要查看其他选项?
我处理这些的正常循环是:
IList<Entities.Access.Revision> result;
IList<int> recordIds = aSession.Query<Entities.Access.Revision>().Select(x => x.Id).ToList<int>();
foreach (int recordId in recordIds)
{
result = aSession.Query<Entities.Access.Revision>().Where(x => x.Id == recordId).ToList<Entities.Access.Revision>();
Save(sqlDb, result);
}
Run Code Online (Sandbox Code Playgroud)
保存功能只是将属性从一个复制到另一个,并且对于某些实体用于操纵数据或向用户提供与数据问题相关的反馈.我正在为两个数据库使用无状态会话.
-
通过进一步测试,它似乎挂在上面的物体大约是60-70mb.我目前正在测试使用GetBytes使用OleDbDataReader获取数据.
-
更新(11月24日):我还没有找到一种方法让它与NHibernate一起使用.我确实使用常规db命令对象.我把以下制作的函数的代码放在任何好奇的人身上.这是我的数据库转换器中的代码,因此前缀为"a"的对象是访问数据库对象,而"s"是sql版本.
public void MigrateBinaryField(int id, string tableName, string fieldName)
{
var aCmd = new OleDbCommand(String.Format(@"SELECT ID, {0} FROM {1} WHERE ID = {2}", …Run Code Online (Sandbox Code Playgroud)