如何通过NHibernate LINQ有效地删除所有没有子实体的父实体?

如何通过NHibernate LINQ有效地删除所有没有子实体的父实体?,nhibernate,Nhibernate,我需要定期清除一些数据库表。清除包括删除所有没有子级的父级。当前实现使用存储过程来完成此任务。我想要的是消除存储过程,并通过NHibernate Linq查询实现删除操作。例如,我需要一个删除所有没有项目的发票的查询。除非您想对数据库进行大量删除查询,然后使用Linq或query进行简短回答,否则您不能,除非您先编写一个ID列表,然后在子查询中使用该列表。一次删除在任何ORM中都可能很麻烦 大多数解决方案都使用存储过程或嵌入式命名查询(SQL或HQL)。除非您想对数据库启动大量删除查询,否则使用

我需要定期清除一些数据库表。清除包括删除所有没有子级的父级。当前实现使用存储过程来完成此任务。我想要的是消除存储过程,并通过NHibernate Linq查询实现删除操作。例如,我需要一个删除所有没有项目的发票的查询。

除非您想对数据库进行大量删除查询,然后使用Linq或query进行简短回答,否则您不能,除非您先编写一个ID列表,然后在子查询中使用该列表。一次删除在任何
ORM中都可能很麻烦


大多数解决方案都使用存储过程或嵌入式命名查询(SQL或HQL)。

除非您想对数据库启动大量删除查询,否则使用Linq或query的简短回答是不可能的,除非您先编写一个ID列表,然后在子查询中使用它。一次删除在任何
ORM中都可能很麻烦


大多数解决方案都使用存储过程或嵌入式命名查询(SQL或HQL)。

使用
查询版本
,您可以找到所有希望删除的
发票
类型的持久对象。但正如里波所说,这将引发几个删除查询。您可以对此稍作修改并创建发票ID数组。然后创建一个SqlQuery,使用
YourSession.CreateSQLQuery
一次删除所有记录

var invoicesToDelete = YourSession.QueryOver<Invoice>().Where(invoice => invoice.items == null).List();
var invoiceIds = new List<int>();
foreach(var invoice in invoicesToDelete)
{
    invoiceIds.Add(invoice.Id);
}
string queryString = "delete from invoice where id in(";
foreach(var id in invoiceIds)
{
    queryString = queryString + id + ",";
}
queryString = queryString.TrimEnd(',');
queryString = queryString + ")";
ISQLQuery query = YourSession.CreateSQLQuery(queryString);
queryString.UniqueResult();
YourSession.Transaction.Commit();
var invoicesToDelete=YourSession.QueryOver().Where(invoice=>invoice.items==null.List();
var invoiceIds=新列表();
foreach(发票中的var发票删除)
{
添加(invoice.Id);
}
string queryString=“从发票中删除id(”;
foreach(InvoiceId中的变量id)
{
queryString=queryString+id+“,”;
}
queryString=queryString.TrimEnd(',');
queryString=queryString+”;
ISQLQuery query=YourSession.CreateSQLQuery(queryString);
queryString.UniqueResult();
YourSession.Transaction.Commit();

代码看起来很凌乱,但效率应该更高。

使用
查询器
,您可以找到您希望删除的
发票
类型的所有持久对象。但正如里波所说,这将引发几个删除查询。您可以对此稍作修改并创建发票ID数组。然后创建一个SqlQuery,使用
YourSession.CreateSQLQuery
一次删除所有记录

var invoicesToDelete = YourSession.QueryOver<Invoice>().Where(invoice => invoice.items == null).List();
var invoiceIds = new List<int>();
foreach(var invoice in invoicesToDelete)
{
    invoiceIds.Add(invoice.Id);
}
string queryString = "delete from invoice where id in(";
foreach(var id in invoiceIds)
{
    queryString = queryString + id + ",";
}
queryString = queryString.TrimEnd(',');
queryString = queryString + ")";
ISQLQuery query = YourSession.CreateSQLQuery(queryString);
queryString.UniqueResult();
YourSession.Transaction.Commit();
var invoicesToDelete=YourSession.QueryOver().Where(invoice=>invoice.items==null.List();
var invoiceIds=新列表();
foreach(发票中的var发票删除)
{
添加(invoice.Id);
}
string queryString=“从发票中删除id(”;
foreach(InvoiceId中的变量id)
{
queryString=queryString+id+“,”;
}
queryString=queryString.TrimEnd(',');
queryString=queryString+”;
ISQLQuery query=YourSession.CreateSQLQuery(queryString);
queryString.UniqueResult();
YourSession.Transaction.Commit();

代码看起来很凌乱,但效率应该更高。

目前我正在使用以下构造:使用(var tx=Session.BeginTransaction()){var notNeeded=Session.Query()。其中(m=>!m.Items.Any());foreach(发票不需要){Session.Delete(发票);}tx.Commit();}但这是非常低效的,我会尝试一下,但由于通常有数百张发票需要删除,我也不认为这条路径是有效的。我认为这肯定比向数据库发送单独的删除命令要快。目前我使用的结构是:使用(var tx=Session.BeginTransaction()){var notNeeded=Session.Query().Where(m=>!m.Items.Any());foreach(发票在notNeeded中){Session.Delete(发票);}tx.Commit();}但这是非常低效的,我会尝试一下,但由于通常有数百张发票需要删除,我也不认为这是有效的。我认为这肯定比发送单个删除命令到数据库要快。