在我的系统中,我有两个实体 - ShoppingCart和ShoppingCartItem.相当通用的用例.但是,当我保存我的ShoppingCart时,没有任何项目保存到数据库中.
在我的对象中,我创建了一个新的ShoppingCart对象.
ShoppingCart cart = CreateOrGetCart();
Run Code Online (Sandbox Code Playgroud)
然后,我将从数据库中获得的现有产品添加到开头.
cart.AddItem(product);
Run Code Online (Sandbox Code Playgroud)
这只是将项添加到IList的简单包装器.
public virtual void AddItem(Product product)
{
Items.Add(new ShoppingCartItem { Quantity = 1, Product = product });
}
Run Code Online (Sandbox Code Playgroud)
然后我在Repository上调用SaveOrUpdate
Repository.SaveOrUpdate(cart);
Run Code Online (Sandbox Code Playgroud)
看起来像这样:
public T SaveOrUpdate(T entity)
{
Session.SaveOrUpdate(entity);
return entity;
}
Run Code Online (Sandbox Code Playgroud)
我正在使用Fluent NHibernate进行映射:
public ShoppingCartItemMap()
{
WithTable("ShoppingCartItems");
Id(x => x.ID, "ShoppingCartItemId");
Map(x => x.Quantity);
References(x => x.Cart, "ShoppingCartId").Cascade.SaveUpdate();
References(x => x.Product, "ProductId");
}
public ShoppingCartMap()
{
WithTable("ShoppingCarts");
Id(x => x.ID, "ShoppingCartId");
Map(x => x.Created);
Map(x => x.Username);
HasMany<ShoppingCartItem>(x => x.Items)
.IsInverse().Cascade.SaveUpdate() …Run Code Online (Sandbox Code Playgroud) 我有以下(简化)
public enum Level
{
Bronze,
Silver,
Gold
}
public class Member
{
public virtual Level MembershipLevel { get; set; }
}
public class MemberMap : ClassMap<Member>
{
Map(x => x.MembershipLevel);
}
Run Code Online (Sandbox Code Playgroud)
这将创建一个表,其中包含名为MembershipLevel的列,其值为Enum字符串值.
我想要的是将整个枚举创建为查找表,其中成员表引用它作为FK的整数值.
另外,我想在不改变模型的情况下这样做.
我有一些类从非常精细的表中读取,这就是为什么我希望它们被NHibernate用作"ReadOnly".在每个字段映射上建立.ReadOnly()非常草率,我不确定我是否相信它.我如何设置一个完全只读的类,因为我可以轻松地使用传统的XML映射?
编辑:答案确实有效.我期望它在我试图保存ReadOnly()对象时抛出异常,但它只是默默地这样做.
谢谢.
使用FNH,我尝试使用以下方法检索类别:
_session.QueryOver<Data.Model.Category>()
.Where(c => tourCreateRequest.Categories.Contains(c.CategoryId))
.List()
.Select(_categoryMapper.CreateCategory)
.ToList();
Run Code Online (Sandbox Code Playgroud)
但是我在.Contains()方法中遇到错误:
无法识别的方法调用:System.Collections.Generic.ICollection`1 [[System.Int64,mscorlib,Version = 4.0.0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089]]:Boolean包含(Int64)
为什么我得到那个错误,出了什么问题?
我浏览了一些帖子,然后将查询更改为(下面),这适用于Query <>.
_session.Query<Data.Model.Category>()
.Where(c => tourCreateRequest.Categories.Contains(c.CategoryId))
.ToList()
.Select(_categoryMapper.CreateCategory)
.ToList();
Run Code Online (Sandbox Code Playgroud)
我认为QueryOver <>是最新的和最好的,应该使用而不是Query <>.
我使用如上所示的QueryOver <>的方式有什么问题?
我使用NHibernate和FluentNHibernate作为我的DAL.我也在使用SchemaExport和SchemaUpdate创建和更新我的数据库模式.
我的问题是模式操作都需要数据库存在才能工作.我想以编程方式创建我的数据库并更新模式,因为可能有多个数据库,并且创建数据库不仅是一次性操作.
我知道我可以通过在与master数据库的连接上执行create database命令来手动执行此操作,但考虑到我否则使用NHibernate进行所有数据库交互,这感觉不对.顺便说一句,我使用SQLite内存数据库进行单元测试,因此我编写的任何sql都必须知道我正在使用哪个数据库.
有没有办法让NHibernate为我创建我的数据库?
我和一位同事最近使用Fluent NHibernate为一个小应用程序做后端.我们编写了实体,映射文件,持久性管理器,但由于某种原因,我们无法将数据库模式导出到任何东西.
通过调试器,我们发现FluentMappings.AddFromAssemblyOf返回0映射,即使它们显然在那里,并且显然是正确的.我们尝试了我们能想到的一切,最终不得不手动添加每个映射.
以下是无效的代码:
return Fluently.Configure().Database(
MsSqlConfiguration.MsSql2005
.ConnectionString(c => c
.TrustedConnection()
.Server("localhost")
.Database("LDTT")))
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<UserMap>())
.ExposeConfiguration(BuildSchema)
.BuildSessionFactory();
Run Code Online (Sandbox Code Playgroud)
虽然这段代码确实有效:
return Fluently.Configure().Database(
MsSqlConfiguration.MsSql2005
.ConnectionString(c => c
.TrustedConnection()
.Server("localhost")
.Database("LDTT")))
.Mappings(m => m.FluentMappings.Add<ClientMap>())
.Mappings(m => m.FluentMappings.Add<ContactMap>())
.Mappings(m => m.FluentMappings.Add<DepartmentMap>())
.Mappings(m => m.FluentMappings.Add<DivisionMap>())
.Mappings(m => m.FluentMappings.Add<FileMap>())
.Mappings(m => m.FluentMappings.Add<FileTypeMap>())
.Mappings(m => m.FluentMappings.Add<RegionMap>())
.Mappings(m => m.FluentMappings.Add<TimeEntryMap>())
.Mappings(m => m.FluentMappings.Add<UserMap>())
.ExposeConfiguration(BuildSchema)
.BuildSessionFactory();
Run Code Online (Sandbox Code Playgroud)
有谁知道为什么会这样,以及如何解决它?
我的数据库架构有一个字符串作为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' …