C# NHibernate查询超过复杂查询
我目前正在开发一个c#、MVC3、NHibernate(在MSSQL 2008上)应用程序。 我将提供一个简化的示例,因为我认为这是理解这一点的最佳方式 型号:C# NHibernate查询超过复杂查询,c#,nhibernate,C#,Nhibernate,我目前正在开发一个c#、MVC3、NHibernate(在MSSQL 2008上)应用程序。 我将提供一个简化的示例,因为我认为这是理解这一点的最佳方式 型号: class Stock { public Company Company {get;set;} public Product Product {get;set;} public int quantity {get;set;} } class TransactionHeader { publi
class Stock
{
public Company Company {get;set;}
public Product Product {get;set;}
public int quantity {get;set;}
}
class TransactionHeader
{
public Company FromCompany {get;set;}
public Company ToCompany {get;set;}
public IList<TransactionRow> Rows {get;set;}
}
class TransactionRows
{
public Product Product {get;set;}
public TransactionHeader Header {get;set;}
public int Quantity {get;set;}
}
class Company
{
public Country Country {get;set;}
public State State {get;set;}
public string Name {get;set;}
}
编辑2:所需SQL的第二个版本
SELECT
c.Id CompanyId,
c.Description CompanyName,
p.Id ProductId,
p.Description ProductName,
cs.Description StateName,
cc.Description CountryName,
SUM(s.CurrentStock) CurrentStock,
SUM(ttr.Quantity) IncommingStock,
SUM(ftr.Quantity) OutgoingStock
FROM Stock s
INNER JOIN Company c ON c.Id = s.Company
INNER JOIN [State] cs ON cs.Id = c.[State]
INNER JOIN Country cc ON cc.Id = cs.Country
INNER JOIN Product p ON p.Id = s.Product
LEFT JOIN TransactionHeader fth ON fth.FromCompany = c.Id
LEFT JOIN TransactionRow ftr ON ftr.TransactionHeader = fth.ID
AND ftr.Product = p.Id
LEFT JOIN TransactionHeader tth ON tth.ToCompany = c.Id
LEFT JOIN TransactionRow ttr ON ttr.TransactionHeader = tth.ID
AND ttr.Product = p.Id
WHERE (@CompanyId IS NULL OR c.Id = @CompanyId) AND
(@CountryId IS NULL OR cc.Id = @CountryId) AND
(@StateId IS NULL OR cs.Id = @StateId) AND
(@ProductId IS NULL OR p.Id = @ProductId)
GROUP BY p.Id, c.Id, c.Description, p.Description,
cs.Description, cc.Description
非常感谢Andrew,他促使我写出了SQL,从而解决了这个问题 在设置方面,我遗漏了一些东西:
public virtual IList<TransactionHeader> TransactionsFromCompany { get; set; }
public virtual IList<TransactionHeader> TransactionsToCompany { get; set; }
public虚拟IList TransactionsFromCompany{get;set;}
公共虚拟IList事务处理公司{get;set;}
.Override<Company>(m =>
{
m.HasMany(c => c.TransactionsFromCompany)
.KeyColumn("FromCompany");
m.HasMany(c => c.TransactionsToCompany)
.KeyColumn("ToCompany");
}
.Override(m=>
{
m、 有许多(c=>c.TransactionfromCompany)
.KeyColumn(“来自公司”);
m、 HasMany(c=>c.TransactionsToCompany)
.KeyColumn(“公司”);
}
StockLevelRowVM rowVM = null;
Stock s = null;
Company c = null;
State state = null;
Country country = null;
Product p = null;
TransactionHeader ith = null;
TransactionRow itr = null;
TransactionHeader oth = null;
TransactionRow otr = null;
var stockQuery = session.QueryOver<Stock>(() => s)
.JoinAlias<Company>(() => s.company, () => c, NHibernate.SqlCommand.JoinType.InnerJoin, null)
.JoinAlias<State>(() => c.State, () => state, NHibernate.SqlCommand.JoinType.InnerJoin, null)
.JoinAlias<Country>(() => c.Country, () => country, NHibernate.SqlCommand.JoinType.InnerJoin, null)
.JoinAlias<Product>(() => s.product, () => p, NHibernate.SqlCommand.JoinType.InnerJoin, null)
.JoinAlias<TransactionHeader>(() => c.TransactionsFromCompany, () => oth, NHibernate.SqlCommand.JoinType.LeftOuterJoin, null)
.JoinAlias<TransactionRow>(() => oth.Rows, () => otr, NHibernate.SqlCommand.JoinType.LeftOuterJoin, null)
.JoinAlias<TransactionHeader>(() => c.TransactionsToCompany, () => ith, NHibernate.SqlCommand.JoinType.LeftOuterJoin, null)
.JoinAlias<TransactionRow>(() => ith.Rows, () => itr, NHibernate.SqlCommand.JoinType.LeftOuterJoin, null);
if (productId.HasValue) { stockQuery = stockQuery.Where(() => p.Id == productId); }
if (companyId.HasValue) { stockQuery = stockQuery.Where(() => c.Id == companyId); }
if (stateId.HasValue) { stockQuery = stockQuery.Where(() => state.Id == stateId); }
if (countryId.HasValue) { stockQuery = stockQuery.Where(() => country.Id == countryId); }
<call generic paging methods for IQueryOver>
result = stockQuery.SelectList(list => list
.SelectGroup(() => c.Id)
.SelectGroup(() => p.Id)
.SelectGroup(() => c.Description).WithAlias(() => rowVM.CompanyName)
.SelectGroup(() => state.Description).WithAlias(() => rowVM.StateName)
.SelectGroup(() => country.Description).WithAlias(() => rowVM.CountryName)
.SelectGroup(() => p.Description).WithAlias(() => rowVM.ProductName)
.SelectSum(() => s.currentStock).WithAlias(() => rowVM.CurrentStock)
.SelectSum(() => otr.Quantity).WithAlias(() => rowVM.OutgoingStock)
.SelectSum(() => itr.Quantity).WithAlias(() => rowVM.IncommingStock))
.TransformUsing(Transformers.AliasToBean<StockLevelRowVM>())
.List<StockLevelRowVM>().ToList();
StockLevelRowVM-rowVM=null;
股票s=null;
公司c=null;
State=null;
Country=null;
乘积p=null;
TransactionHeader ith=null;
TransactionRow itr=null;
TransactionHeader oth=null;
TransactionRow otr=null;
var stockQuery=session.QueryOver(()=>s)
.JoinAlias(()=>s.company,()=>c,NHibernate.SqlCommand.JoinType.InnerJoin,null)
.JoinAlias(()=>c.State,()=>State,NHibernate.SqlCommand.JoinType.InnerJoin,null)
.JoinAlias(()=>c.Country,()=>Country,NHibernate.SqlCommand.JoinType.InnerJoin,null)
.JoinAlias(()=>s.product,()=>p,NHibernate.SqlCommand.JoinType.InnerJoin,null)
.JoinAlias(()=>c.TransactionsFromCompany,()=>oth,NHibernate.SqlCommand.JoinType.LeftOuterJoin,null)
.JoinAlias(()=>oth.Rows,()=>otr,NHibernate.SqlCommand.JoinType.LeftOuterJoin,null)
.JoinAlias(()=>c.TransactionsToCompany,()=>ith,NHibernate.SqlCommand.JoinType.LeftOuterJoin,null)
.JoinAlias(()=>ith.Rows,()=>itr,NHibernate.SqlCommand.JoinType.LeftOuterJoin,null);
if(productId.HasValue){stockQuery=stockQuery.Where(()=>p.Id==productId);}
if(companyId.HasValue){stockQuery=stockQuery.Where(()=>c.Id==companyId);}
if(stateId.HasValue){stockQuery=stockQuery.Where(()=>state.Id==stateId);}
if(countryId.HasValue){stockQuery=stockQuery.Where(()=>country.Id==countryId);}
结果=stockQuery.SelectList(列表=>list
.SelectGroup(()=>c.Id)
.SelectGroup(()=>p.Id)
.SelectGroup(()=>c.Description)。别名为(()=>rowVM.CompanyName)
.SelectGroup(()=>state.Description)。带别名(()=>rowVM.StateName)
.SelectGroup(()=>country.Description)。别名为(()=>rowVM.CountryName)
.SelectGroup(()=>p.Description)。带别名(()=>rowVM.ProductName)
.SelectSum(()=>s.currentStock)。带别名(()=>rowVM.currentStock)
.SelectSum(()=>otr.Quantity)。别名为(()=>rowVM.OutgoingStock)
.SelectSum(()=>itr.Quantity)。带别名(()=>rowVM.IncommingStock))
.TransformUsing(Transformers.AliasToBean())
.List().ToList();
你能展示一下你希望生成的SQL吗?这样做会更容易找到查询结果。@AndrewHitaker我没有SQL,但把一些SQL拼凑在一起并添加到了问题中。它可能不是100%正确,但希望能传达出我想要实现的目标。嗯,你不可能做到
UNION
或使用QueryOver从表表达式(from(select…
)中进行选择。啊,好吧。我想我会选择存储过程路线。感谢您的关注。我添加了另一种可能更可行的预期SQL变体。它也可能会稍微慢一些……目前还不确定。
SELECT
c.Id CompanyId,
c.Description CompanyName,
p.Id ProductId,
p.Description ProductName,
cs.Description StateName,
cc.Description CountryName,
SUM(s.CurrentStock) CurrentStock,
SUM(ttr.Quantity) IncommingStock,
SUM(ftr.Quantity) OutgoingStock
FROM Stock s
INNER JOIN Company c ON c.Id = s.Company
INNER JOIN [State] cs ON cs.Id = c.[State]
INNER JOIN Country cc ON cc.Id = cs.Country
INNER JOIN Product p ON p.Id = s.Product
LEFT JOIN TransactionHeader fth ON fth.FromCompany = c.Id
LEFT JOIN TransactionRow ftr ON ftr.TransactionHeader = fth.ID
AND ftr.Product = p.Id
LEFT JOIN TransactionHeader tth ON tth.ToCompany = c.Id
LEFT JOIN TransactionRow ttr ON ttr.TransactionHeader = tth.ID
AND ttr.Product = p.Id
WHERE (@CompanyId IS NULL OR c.Id = @CompanyId) AND
(@CountryId IS NULL OR cc.Id = @CountryId) AND
(@StateId IS NULL OR cs.Id = @StateId) AND
(@ProductId IS NULL OR p.Id = @ProductId)
GROUP BY p.Id, c.Id, c.Description, p.Description,
cs.Description, cc.Description
public virtual IList<TransactionHeader> TransactionsFromCompany { get; set; }
public virtual IList<TransactionHeader> TransactionsToCompany { get; set; }
.Override<Company>(m =>
{
m.HasMany(c => c.TransactionsFromCompany)
.KeyColumn("FromCompany");
m.HasMany(c => c.TransactionsToCompany)
.KeyColumn("ToCompany");
}
StockLevelRowVM rowVM = null;
Stock s = null;
Company c = null;
State state = null;
Country country = null;
Product p = null;
TransactionHeader ith = null;
TransactionRow itr = null;
TransactionHeader oth = null;
TransactionRow otr = null;
var stockQuery = session.QueryOver<Stock>(() => s)
.JoinAlias<Company>(() => s.company, () => c, NHibernate.SqlCommand.JoinType.InnerJoin, null)
.JoinAlias<State>(() => c.State, () => state, NHibernate.SqlCommand.JoinType.InnerJoin, null)
.JoinAlias<Country>(() => c.Country, () => country, NHibernate.SqlCommand.JoinType.InnerJoin, null)
.JoinAlias<Product>(() => s.product, () => p, NHibernate.SqlCommand.JoinType.InnerJoin, null)
.JoinAlias<TransactionHeader>(() => c.TransactionsFromCompany, () => oth, NHibernate.SqlCommand.JoinType.LeftOuterJoin, null)
.JoinAlias<TransactionRow>(() => oth.Rows, () => otr, NHibernate.SqlCommand.JoinType.LeftOuterJoin, null)
.JoinAlias<TransactionHeader>(() => c.TransactionsToCompany, () => ith, NHibernate.SqlCommand.JoinType.LeftOuterJoin, null)
.JoinAlias<TransactionRow>(() => ith.Rows, () => itr, NHibernate.SqlCommand.JoinType.LeftOuterJoin, null);
if (productId.HasValue) { stockQuery = stockQuery.Where(() => p.Id == productId); }
if (companyId.HasValue) { stockQuery = stockQuery.Where(() => c.Id == companyId); }
if (stateId.HasValue) { stockQuery = stockQuery.Where(() => state.Id == stateId); }
if (countryId.HasValue) { stockQuery = stockQuery.Where(() => country.Id == countryId); }
<call generic paging methods for IQueryOver>
result = stockQuery.SelectList(list => list
.SelectGroup(() => c.Id)
.SelectGroup(() => p.Id)
.SelectGroup(() => c.Description).WithAlias(() => rowVM.CompanyName)
.SelectGroup(() => state.Description).WithAlias(() => rowVM.StateName)
.SelectGroup(() => country.Description).WithAlias(() => rowVM.CountryName)
.SelectGroup(() => p.Description).WithAlias(() => rowVM.ProductName)
.SelectSum(() => s.currentStock).WithAlias(() => rowVM.CurrentStock)
.SelectSum(() => otr.Quantity).WithAlias(() => rowVM.OutgoingStock)
.SelectSum(() => itr.Quantity).WithAlias(() => rowVM.IncommingStock))
.TransformUsing(Transformers.AliasToBean<StockLevelRowVM>())
.List<StockLevelRowVM>().ToList();