我一直在寻找一些关于Linq到Nhibernate的示例项目或教程.
有谁知道任何好的?
为了保持我的集成测试独立,我删除所有旧数据并在每次测试之前插入新的测试数据.有没有比仅仅查询所有实体并逐个删除它们更好的方法呢?
我考虑过编写一个运行"从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级缓存.
我发现了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) 我正在尝试使用linq到NHibernate(使用Fluent NHibernate)但是我遇到了linq查询的问题.每次我尝试执行它时,我收到此消息:
" 方法'get_IsReadOnlyInitialized’型'NHibernate.Linq.Util.DetachedCriteriaAdapter’自组装'NHibernate.Linq,版本= 1.1.0.1001,文化=中立,公钥=空’没有实现. "
有人知道如何解决这个问题吗?我尝试使用模型上下文的这个页面的解决方案,但它没有帮助.
这是代码:
using(var session = NHibernateHelper.OpenSession())
{
var informations = (from i in session<Information>() where i.Text=="some text" select i).ToList();
}
Run Code Online (Sandbox Code Playgroud)
一切都很好,如果我不使用where部分,但如果我使用它我得到这个错误.我认为问题出在NHibernate.Linq.dll中
C#的新版本就在那里,有了新的功能元组类型:
public IQueryable<T> Query<T>();
public (int id, string name) GetSomeInfo() {
var obj = Query<SomeType>()
.Select(o => new {
id = o.Id,
name = o.Name,
})
.First();
return (id: obj.id, name: obj.name);
}
Run Code Online (Sandbox Code Playgroud)
有没有办法将我的匿名类型对象obj转换为我想要返回的元组而没有按属性映射属性(假设属性的名称匹配)?
上下文在ORM中,我的SomeType对象有很多其他属性,它被映射到包含大量列的表.我想做一个只带来ID和NAME的查询,所以我需要将匿名类型转换为元组,或者我需要ORM Linq Provider知道如何理解元组并将属性相关列放在SQL select子句中.
linq-to-entities tuples anonymous-types linq-to-nhibernate c#-7.0
我正在使用FluentNHibernate和NH 3.0,使用LINQ提供程序和新的QueryOver语法.
现在使用QueryOver我想得到一个项目(称为结果),其时间戳值尽可能接近给定值,但不是更大:
Result precedingOrMatchingResult = Session.QueryOver<Result>().
Where(r => r.TimeStamp < timeStamp).
OrderBy(r => r.TimeStamp).Desc.
FirstOrDefault(); //get the preceding or matching result, if there is any
Run Code Online (Sandbox Code Playgroud)
现在,Intellisense告诉我,没有一种FirstOrDefault()方法.当然,我可以枚举我的有序查询,然后使用LINQ获取我的项目.但这会首先将所有项目加载到内存中.
有没有替代FirstOrDefault(),或者我理解完全错误的东西?
当我尝试编译以下代码时
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Linq;
using NHibernate;
namespace NewNHTest
{
class A
{ }
class Program
{
static void Main(string[] args)
{
ISession session;
var q = session.Query<A>();
}
}
}
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
'NHibernate.ISession' does not contain a definition for 'Query' and no extension method 'Query' accepting a first argument of type 'NHibernate.ISession' could be found (are you missing a using directive or an assembly reference?)
Run Code Online (Sandbox Code Playgroud)
NHibernate.dll版本是3.0.0.4000.
.Net版本的项目是3.5.
我究竟做错了什么?
谢谢您的帮助!
是否有可能让Nhibernate linq生成带有"In"子句的查询?例如 - Where AnID in (x,y,z)?
关于这个问题有几个类似的问题,我还没有找到足够的理由来决定走哪条路.
真正的问题是,是否合理使用存储库模式抽象NHibernate的,或者不是?
似乎抽象它背后的唯一原因是如果需要的话,让自己选择用不同的ORM替换NHibernate.但是创建存储库和抽象查询看起来像添加另一层,并手工完成大部分管道工作.
一种选择是使用IQueryable<T>商业层公开和使用LINQ,但根据我的经验,LINQ支持仍然没有在NHibernate中完全实现(查询根本不能按预期工作,我讨厌花时间调试框架).
尽管在我的业务层中引用NHibernate会伤害我的眼睛,但它本身应该是数据访问的抽象,对吧?
你对此有何看法?
如何使用NHibernate.Linq生成此查询?
WHERE this_.Name LIKE @p0; @p0 = 'test' // Notice NO % wild card
Run Code Online (Sandbox Code Playgroud)
注意,这不是Linq To Sql或Entity Framework.这是NHibernate.
编辑:
以下是使用ICriteria的所需查询:
criteria.Add(Expression.Like("Name", "test"));
return criteria.List<Theater>();
Run Code Online (Sandbox Code Playgroud)