MVC:创建动态组的最佳方式

时间:2013-03-05 08:18:44

标签: sql asp.net-mvc linq entity-framework group-by

我得到了一个项目列表,每次都可以检查和传递。 所选项目将移动到包含这些已检查项目的字符串列表中。

我想学习一种方法,它可以帮助我创建按选择的列分组所需的查询,例如,如果我选中“OperatorTypeName”和“CompanyName”,则会收到相对查询:

SELECT OperatorTypeName AS Group1, Company.CompanyName AS Group2, SUM(Adv.Price) 
AS SumPrice 
FROM Adv  (nolock) 
INNER JOIN Program (nolock) 
    ON Adv.ProgramID = Program.ProgramID 
INNER JOIN Operator (nolock)  
    ON Program.OperatorID = Operator.OperatorID 
INNER JOIN OperatorType (nolock)  
    ON Operator.OperatorTypeID = OperatorType.OperatorTypeID 
INNER JOIN CampaignVersion (nolock) 
    ON Adv.CampaignVersionID = CampaignVersion.CampaignVersionID 
INNER JOIN Campaign ON CampaignVersion.CampaignID = Campaign.CampaignID
INNER JOIN Campaign2Product (nolock) 
    ON Campaign.CampaignID = Campaign2Product.CampaignID 
INNER JOIN Product2Company (nolock) 
    ON Product2Company.ProductID = Campaign2Product.ProductID 
INNER JOIN Product2SubBranch (nolock) 
    ON Product2SubBranch.ProductID = Campaign2Product.ProductID 
INNER JOIN SubBranch (nolock) 
    ON SubBranch.SubBranchID = Product2SubBranch.SubBranchID
INNER JOIN Branch (nolock) 
    ON SubBranch.BranchID = Branch.BranchID
INNER JOIN Company (nolock) 
    ON Product2Company.CompanyID = Company.CompanyID 
INNER JOIN Company Manager (nolock) on Campaign.Manager =Manager.CompanyID 
             WHERE     (Adv.TransmitDate >= getdate()-7)
             GROUP BY  OperatorTypeName , Company.CompanyName

如果仅检查“OperatorTypeName”,则接收针对此条件的相应查询:

SELECT OperatorTypeName AS Group1, SUM(Adv.Price) AS SumPrice 
FROM Adv  (nolock) 
INNER JOIN Program (nolock) 
    ON Adv.ProgramID = Program.ProgramID 
INNER JOIN Operator (nolock)  
    ON Program.OperatorID = Operator.OperatorID 
INNER JOIN OperatorType (nolock)  
    ON Operator.OperatorTypeID = OperatorType.OperatorTypeID 
INNER JOIN CampaignVersion (nolock) 
    ON Adv.CampaignVersionID = CampaignVersion.CampaignVersionID 
INNER JOIN Campaign 
    ON CampaignVersion.CampaignID = Campaign.CampaignID
INNER JOIN Campaign2Product (nolock) 
    ON Campaign.CampaignID = Campaign2Product.CampaignID 
INNER JOIN Product2Company (nolock) 
    ON Product2Company.ProductID = Campaign2Product.ProductID 
INNER JOIN Product2SubBranch (nolock) 
    ON Product2SubBranch.ProductID = Campaign2Product.ProductID 
INNER JOIN SubBranch (nolock) 
    ON SubBranch.SubBranchID = Product2SubBranch.SubBranchID
INNER JOIN Branch (nolock) 
    ON SubBranch.BranchID = Branch.BranchID
INNER JOIN Company (nolock) 
    ON Product2Company.CompanyID = Company.CompanyID 
INNER JOIN Company Manager (nolock) on Campaign.Manager =Manager.CompanyID 
WHERE     (Adv.TransmitDate >= getdate()-7)
GROUP BY  OperatorTypeName

我不想为每一个条件创建每个单独的查询,因为我可以用30个可能的列创建一个组。 我可能希望每次有比最后一个查询更大的查询时调用sql,但是如果我加载了10列而不是我在下一次搜索中只加载其中的2个,则会从会话查询中对其进行分组,但是让我们从基础开始,如何在没有多个案例的情况下让它工作,以手动创建每个查询?

2 个答案:

答案 0 :(得分:1)

这样的事情会做到:

string res = SQL.createSQL("OperatorTypeName");
string res2 = SQL.createSQL("OperatorTypeName", "Company.CompanyName");



public static class SQL
{
    public static string createSQL(params string[] columns)
    {
        string top = string.Empty;
        string bottom = string.Empty;
        for (int i = 0; i < columns.Length; i++)
        {
            if (i > 0)
            {
                top += ", ";
                bottom += ", ";
            }
            top += columns[i];
            bottom += columns[i];
            top += string.Format(" AS Group{0}", i + 1);
        }

        string sql = string.Format("SELECT {0}, SUM(Adv.Price) AS SumPrice " +
            "FROM Adv  (nolock) " +
            "INNER JOIN Program (nolock) " +
                "ON Adv.ProgramID = Program.ProgramID " +
            "INNER JOIN Operator (nolock) " +
                "ON Program.OperatorID = Operator.OperatorID " +
            "INNER JOIN OperatorType (nolock) " +
                "ON Operator.OperatorTypeID = OperatorType.OperatorTypeID " +
            "INNER JOIN CampaignVersion (nolock) " +
                "ON Adv.CampaignVersionID = CampaignVersion.CampaignVersionID " +
            "INNER JOIN Campaign " +
                "ON CampaignVersion.CampaignID = Campaign.CampaignID " +
            "INNER JOIN Campaign2Product (nolock) " +
                "ON Campaign.CampaignID = Campaign2Product.CampaignID " +
            "INNER JOIN Product2Company (nolock) " +
                "ON Product2Company.ProductID = Campaign2Product.ProductID " +
            "INNER JOIN Product2SubBranch (nolock) " +
                "ON Product2SubBranch.ProductID = Campaign2Product.ProductID " +
            "INNER JOIN SubBranch (nolock) " +
                "ON SubBranch.SubBranchID = Product2SubBranch.SubBranchID " +
            "INNER JOIN Branch (nolock) " +
                "ON SubBranch.BranchID = Branch.BranchID " +
            "INNER JOIN Company (nolock) " +
                "ON Product2Company.CompanyID = Company.CompanyID " +
            "INNER JOIN Company Manager (nolock) on Campaign.Manager =Manager.CompanyID " +
            "WHERE     (Adv.TransmitDate >= getdate()-7) " +
            "GROUP BY {1}", top, bottom);

        return sql;
    }
}

答案 1 :(得分:0)

最终代码如下所示:

带有更改的Sql Query构建方法:

public static class SQL
{
    public static string createSQL(params string[] columns)
    {
        string top = string.Empty;
        string bottom = string.Empty;
        for (int i = 0; i < 5; i++)
        {
            if (i > 0)
            {
                top += ", ";
                if (i < columns.Length)
                {
                    bottom += ", ";
                }
            }

            if (i < columns.Length)
            {
                top += columns[i];
                bottom += columns[i];
            }
            else
            {
                top += "null";
            }
            top += string.Format(" AS Group{0}", i + 1);
        }

        string sql = string.Format("SELECT newid() as ID, {0}, SUM(Adv.Price) AS SumPrice " +
            "FROM Adv  (nolock) " +
            "INNER JOIN Program (nolock) " +
                "ON Adv.ProgramID = Program.ProgramID " +
            "INNER JOIN Operator (nolock) " +
                "ON Program.OperatorID = Operator.OperatorID " +
            "INNER JOIN OperatorType (nolock) " +
                "ON Operator.OperatorTypeID = OperatorType.OperatorTypeID " +
            "INNER JOIN CampaignVersion (nolock) " +
                "ON Adv.CampaignVersionID = CampaignVersion.CampaignVersionID " +
            "INNER JOIN Campaign " +
                "ON CampaignVersion.CampaignID = Campaign.CampaignID " +
            "INNER JOIN Campaign2Product (nolock) " +
                "ON Campaign.CampaignID = Campaign2Product.CampaignID " +
            "INNER JOIN Product2Company (nolock) " +
                "ON Product2Company.ProductID = Campaign2Product.ProductID " +
            "INNER JOIN Product2SubBranch (nolock) " +
                "ON Product2SubBranch.ProductID = Campaign2Product.ProductID " +
            "INNER JOIN SubBranch (nolock) " +
                "ON SubBranch.SubBranchID = Product2SubBranch.SubBranchID " +
            "INNER JOIN Branch (nolock) " +
                "ON SubBranch.BranchID = Branch.BranchID " +
            "INNER JOIN Company (nolock) " +
                "ON Product2Company.CompanyID = Company.CompanyID " +
            "INNER JOIN Company Manager (nolock) on Campaign.Manager =Manager.CompanyID " +
            "WHERE     (Adv.TransmitDate >= getdate()-7) " +
            "GROUP BY {1}", top, bottom);

        return sql;
    }
}

除了dbcontext和构建的查询之外的Enumarating方法:

        public IEnumerable<GroupModel> GroupToEnum(DBS dbs, string query)
    {


        IEnumerable<GroupModel> grp = dbs.Groups.SqlQuery(query);


        return grp;
    }

从控制器调用这些方法,如下所示:

            string res = SQL.createSQL(checked_strings);
        oGrp = qData.GroupToEnum(context, res);

在更多设置后返回视图:

return View("GroupTest", oGrp.ToPagedList(pageNumber, pageSize));