为了保持我的集成测试独立,我删除所有旧数据并在每次测试之前插入新的测试数据.有没有比仅仅查询所有实体并逐个删除它们更好的方法呢?
我考虑过编写一个运行"从tablename删除"的存储过程; 对于要清除的每个表.这应该快得多,但如果不进行SQL查询或通过NH调用SP,这样做会很好.
我正在使用vanilla NHibernate和Linq来NHibernate.我相信Castle Active Record有类似Foo.DeleteAll()的东西,但我不想在这个项目中使用Active Record.
有任何想法吗?
谢谢/ Erik
更新:
自从提出并回答了这个问题以来,NHibernate团队取得了进展.正如Ayende在本博文中解释的那样,您现在可以直接执行DML查询,而无需NHibernate获取任何实体.
要删除所有Foo对象,您可以这样做:
using (ISession session = ...)
using (ITransaction transaction = session.BeginTransaction())
{
session.CreateQuery("delete Foo f").ExecuteUpdate();
transaction.Commit();
}
Run Code Online (Sandbox Code Playgroud)
此查询将生成以下SQL:
delete from Foo
Run Code Online (Sandbox Code Playgroud)
这要比首先获取实体然后删除实体要快得多.但要小心,因为像这样的查询不会影响1级缓存.
所以ADO.NET实体框架已经受到了一些不好的压力(以博客条目和请愿的形式),但我不想急于做出判断.我在实验方面的时间有限,但我想知道有没有人与它合作过更多的经验反馈?
最后,关于使用NHibernate的想法是什么,它已经存在了很长时间,可能比ADO.NET实体框架更成熟.
我发现了2个类似的问题:
根据这个页面:
注意不要急于同时获取多个集合属性.虽然这个声明可以正常工作:
Run Code Online (Sandbox Code Playgroud)var employees = session.Query<Employee>() .Fetch(e => e.Subordinates) .Fetch(e => e.Orders).ToList();它对数据库执行笛卡尔积产品查询,因此返回的总行数将是总下属乘以总订单数.
可以说我有以下型号:
public class Person
{
public virtual int Id { get; private set; }
public virtual ICollection<Book> Books { get; set; }
public virtual ICollection<Article> Articles { get; set; }
public virtual ICollection<Address> Addresses { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
使用QueryOver/Linq(不返回笛卡尔积),急切地使用书籍,文章和地址加载所有人的最简单方法是什么?
谢谢
更新:
见cremor的回答下面和弗洛里安林的回答在这个线程.以下代码很好地工作,只有一次往返数据库.
var persons = session.QueryOver<Person>()
.Future<Person>();
var persons2 = session.QueryOver<Person>() …Run Code Online (Sandbox Code Playgroud) 对于以下错误:
无法加载文件或程序集 '文件:/// C:\ Program Files文件\ SAP的BusinessObjects\SAP BusinessObjects Enterprise的XI 4.0\win32_x86\dotnet1\crdb_adoplus.dll' 或它的一个依赖.
有没有办法解决此错误,而不是通过解决方案:
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0"/>
</startup>
Run Code Online (Sandbox Code Playgroud)
该解决方案在我的应用程序中无效
我有一个NHibernate会话.在这个会话中,我正在执行1个操作,即运行此代码以获取列表:
public IList<Customer> GetCustomerByFirstName(string customerFirstName)
{
return _session.CreateCriteria(typeof(Customer))
.Add(new NHibernate.Expression.EqExpression("FirstName", customerFirstName))
.List<Customer>();
}
Run Code Online (Sandbox Code Playgroud)
我打电话Session.Flush()到最后HttpRequest,我得到了一个HibernateAdoException.NHibernate将更新语句传递给db,并导致外键违规.如果我不运行flush,请求完成没有问题.这里的问题是,如果在其他会话中发生更改,我需要刷新,因为此代码在其他区域中重用.是否有其他配置设置我可能会丢失?
这是异常的代码:
[SQL: UPDATE CUSTOMER SET first_name = ?, last_name = ?, strategy_code_1 = ?, strategy_code_2 = ?, strategy_code_3 = ?, dts_import = ?, account_cycle_code = ?, bucket = ?, collector_code = ?, days_delinquent_count = ?, external_status_code = ?, principal_balance_amount = ?, total_min_pay_due = ?, current_balance = ?, amount_delinquent = ?, current_min_pay_due = ?, bucket_1 = ?, bucket_2 = …Run Code Online (Sandbox Code Playgroud) 我很难理解HiLo发生器在NHibernate中的工作原理.我已经阅读了这里的解释,这使得事情变得更加清晰.
我的理解是每个SessionFactory都从数据库中检索高值.这样可以提高性能,因为我们可以访问ID而无需访问数据库.
上述链接的解释还说明:
例如,假设您有一个当前值为35的"高"序列,而"低"号则在0-1023范围内.然后客户端可以将序列递增到36(对于其他客户端,当它使用35时能够生成密钥)并且知道密钥35/0,35/1,35/2,35/3 ... 35/1023是全部可用.
这是如何在Web应用程序中工作的,因为我只有一个SessionFactory,因此只有一个hi值.这是否意味着在断开连接的应用程序中,您最终可能会在实体表中出现重复(低)ID?
在我的测试中,我使用了以下设置:
<id name="Id" unsaved-value="0">
<generator class="hilo"/>
</id>
Run Code Online (Sandbox Code Playgroud)
我跑了一个测试来保存100个对象.我的表中的ID从32768 - 32868开始.下一个hi值增加到2.然后我再次运行测试,Ids在65536 - 65636范围内.
首先,为什么从32768而不是1开始,其次为什么从32868跳到65536?
现在我知道我的代理键不应该有任何意义,但我们在我们的应用程序中使用它们.为什么我不能让它们像SQL Server身份字段那样很好地增加.
最后有人能给我一个max_lo参数如何工作的解释吗?这是可以针对高值创建的最小低值(我脑中的实体ID)的数量吗?
这是NHibernate中的一个主题,我一直在努力寻找文档.我在动作书中阅读了整个NHibernate,但它仍然没有详细介绍它的工作原理.
谢谢Ben
我使用NHibernate作为我的dataacess,有一段时间我并没有使用SQLite进行本地集成测试.我一直在使用文件,但我想我会把:memory:选项.当我启动任何集成测试时,似乎创建了数据库(NHibernate吐出表创建sql)但是与数据库交互会导致错误.
有没有人让NHibernate与内存数据库一起工作?它甚至可能吗?我正在使用的连接字符串是这样的:
Data Source=:memory:;Version=3;New=True
Run Code Online (Sandbox Code Playgroud) 任何人都可以快速概述一下使用TransactionScope和NHibernate吗?我是否需要对session/IEnlistmentNotification/etc执行任何特殊操作.让这个工作?有什么陷阱我应该担心吗?例如,我可以替换所有的hibernate事务:
var transaction = session.BeginTransaction();
try
{
// code
transaction.Commit();
}
catch (Exception)
{
transaction.Rollback();
}
Run Code Online (Sandbox Code Playgroud)
有了这个?:
using (var scope = new TransactionScope())
{
// code
scope.Complete();
}
Run Code Online (Sandbox Code Playgroud) 我一直在阅读有关Command Query Responsibility Segregation(CQRS)的信息.我有点想知道如何使用ASP.NET MVC?我从概念上理解了CQRS,听起来不错,肯定会引入一些复杂性(事件和消息模式)与"普通/常见"方法相比.CQRS的思想也在某种程度上反对使用ORM.我正在考虑如何在即将到来的项目中使用这种模式,所以如果有人有将CQRS与ASP.NET MVC和NHibernate结合的经验,请提供一些具体的例子来帮助我更好地理解CQRS并与ASP.NET MVC一起使用.谢谢!
更新:我一直在浏览Mark的示例代码.如果您正在学习CQRS,那必读.
http://github.com/MarkNijhof/Fohjin
http://cre8ivethought.com/blog/2009/11/12/cqrs--la-greg-young/
http://cre8ivethought.com/blog/2009/11/28/cqrs-trying-to-make-it-re-usable/
我想知道是否有其他程序或方式来配置除NHibernate探查器之外.我的试用用完了,我买不起它.
那么还有其他选择吗?
nhibernate ×10
c# ×3
orm ×3
.net ×2
ado.net ×1
asp.net-mvc ×1
cqrs ×1
nhprof ×1
queryover ×1
sqlite ×1