从LINQ结果中删除NHibernate

从LINQ结果中删除NHibernate,linq,nhibernate,Linq,Nhibernate,我想知道nhibernate中delete方法的最佳用法 如果您转到实体,则不只是调用delete并发送它,如果不是,则需要查询它或编写查询并将其发送到delete方法 我想知道是否可以编写一个linq表达式并将其发送到delete 是否可以执行到hql的Linq转换,然后调用session.Delete(查询) 使用生成的hql 我想调用Session.Delete,并给它一个linq,这样它就可以在不选择数据的情况下知道要删除什么。您知道一个可以将linq表达式转换为hql的类吗?linq中

我想知道nhibernate中delete方法的最佳用法

如果您转到实体,则不只是调用delete并发送它,如果不是,则需要查询它或编写查询并将其发送到delete方法

我想知道是否可以编写一个linq表达式并将其发送到delete

是否可以执行到hql的Linq转换,然后调用session.Delete(查询) 使用生成的hql

我想调用Session.Delete,并给它一个linq,这样它就可以在不选择数据的情况下知道要删除什么。您知道一个可以将linq表达式转换为hql的类吗?

linq中的Q代表“查询”。所以,不,不能使用LINQ表达式进行删除

也就是说,NH的查询语言HQL确实支持这一点

与您可以说“from Foo where Bar=:something”以获得与某个条件匹配的所有Foo的方式相同,您可以这样做:

session.CreateQuery("delete Foo where Bar = :something")
       .SetParameter("something", ...)
       .ExecuteUpdate();

我相信你可以做你想做的事情,但底线是这没有多大意义(不知道为什么你想给NHibernate选择标准,当你可以在一个语句中完成时,你的方法会导致数据库被点击两次),你可以做一个简单的选择,使用LINQ查询ID并将其传递给NHibernate

int[] deleteIds = (from c in Customer where {some condition} select c.Id).ToArray<int>();

session.CreateQuery("delete Customer c where c.id in (:deleteIds)")
            .SetParameterList("deleteIds", deleteIds)
            .ExecuteUpdate();
int[]deleteID=(从客户中的c中,{some condition}选择c.Id);
CreateQuery(“删除客户c,其中c.id位于(:deleteID)”中)
.SetParameterList(“删除ID”,删除ID)
.ExecuteUpdate();

我已经提交了NH-3659的请求-强类型删除。该链接可从nhibernate.jira.com/browse/NH-3659获得。

您现在可以使用nhibernate 5.0直接在linq中使用

    //
    // Summary:
    //     Delete all entities selected by the specified query. The delete operation is
    //     performed in the database without reading the entities out of it.
    //
    // Parameters:
    //   source:
    //     The query matching the entities to delete.
    //
    // Type parameters:
    //   TSource:
    //     The type of the elements of source.
    //
    // Returns:
    //     The number of deleted entities.
    public static int Delete<TSource>(this IQueryable<TSource> source);
//
//总结:
//删除指定查询选择的所有实体。删除操作是无效的
//在数据库中执行,而不从中读取实体。
//
//参数:
//资料来源:
//与要删除的实体匹配的查询。
//
//类型参数:
//t来源:
//源的元素的类型。
//
//返回:
//已删除实体的数量。
公共静态int Delete(此IQueryable源);
例如:

        var tooOldDate = System.DateTime.Now.AddYears(5);
        session.Query<User>()
            .Where(u => u.LastConnection <= tooOldDate)
            .Delete();
var tooOldDate=System.DateTime.Now.AddYears(5);
session.Query()

.Where(u=>u.LastConnection我知道这是一个老问题,但对于现在阅读本文的人来说。2017年10月10日发布的NHibernate 5添加了删除Linq扩展

从文件 Delete方法扩展需要一个定义要删除的实体的可查询项。它会立即删除这些实体

session.Query<Cat>()
    .Where(c => c.BodyWeight > 20)
    .Delete();
session.Query()
.式中(c=>c.体重>20)
.Delete();

您可以对会话使用查询。删除会话。删除(字符串查询)(它将删除查询返回的所有对象我真的认为这是应该添加到NHibernate.Linq的内容。可能是ISession中的一个扩展方法,它添加了一个接受Linq表达式的delete方法。如果我的内存没有问题,NHibernate中的Linq提供程序会将其转换为NHibernate标准,因此可能会这样做。)如果不需要两次访问服务器就可以删除,并且不必再次求助于HQL,那就太好了。类似这样的内容:session.delete(session.Query(e=>e.Name==“Loudenvier”))并在DELETE语句中进行转换!我相信我在之前的评论中确实把事情搞砸了…为了集思广益,我将让它出现…但我认为最好的解决方案可能类似于Fetch(),FetchMany()方法…只是添加了一个DELETE()也许可以……请记住,我不是NHibernate和Linq方面的专家,我只是一个在这个问题上有着疯狂投机想法的闲人:-)@Chen我确实理解它。但是你想做的是不可能的。你不能用Linq做那件事,用HQL。@Diego很抱歉提出一个老的讨论,但我不同意。是的,Linq是一种质疑(一种综合语言),但返回要删除的结果的查询没有任何错误。SQL delete语句是相同的,返回要删除的结果的查询,而不是返回到客户端。ISession将有两个扩展方法,一个称为返回linq结果的查询,另一个称为delete。删除将使用不同的IQueryProvider执行相同的表达式树分析,但将其放入delete语句中。@DiegoMijelshon“LINQ中的Q代表“查询”。因此,不,不能使用LINQ表达式进行删除。”--第一句话只是神秘化,HQL或SQL中的“Q”代表什么?:)谢谢,但是我想避免去db的两次往返。