Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/269.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# NHibernate查询超过复杂查询_C#_Nhibernate - Fatal编程技术网

C# NHibernate查询超过复杂查询

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

我目前正在开发一个c#、MVC3、NHibernate(在MSSQL 2008上)应用程序。 我将提供一个简化的示例,因为我认为这是理解这一点的最佳方式

型号:

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();