简体   繁体   English

使用 INNER JOIN 将 SQL 查询转换为实体 SQL 查询 - C#

[英]Translation of SQL query with INNER JOIN to Entity SQL query - C#

I build the following SQL query dynamically:我动态构建以下 SQL 查询:

StringBuilder query = new StringBuilder();
StringBuilder query2 = new StringBuilder();

if (ComboRuleType.Text.Equals("Standard"))
{
    query.Append("select * from [dbo].[" + ComboRuleTableName.Text + "]" + " WHERE" + "\n");
    query.Append("(" + "\n");

    for (int i = 0; i < dgvUpdateCriteria.RowCount; i++)
    {
        DataGridViewRow row = dgvUpdateCriteria.Rows[i];

        if (i != 0)
        {
            query.Append(row.Cells[1].Value.ToString() + " " + row.Cells[3].Value.ToString() + " ");
        }
        else
        {
            query.Append(row.Cells[3].Value.ToString() + " ");
        }

        if (row.Cells[4].Value.ToString().Equals("Contains"))
        {
            query.Append("like " + "'%" + row.Cells[5].Value.ToString() + "%'" + "\n");
        }
        else if (row.Cells[4].Value.ToString().Equals("Equals"))
        {
            query.Append("= " + "'" + row.Cells[5].Value.ToString() + "'" + "\n");
        }
        else if (row.Cells[4].Value.ToString().Equals("StartsWith"))
        {
            query.Append("like " + "'" + row.Cells[5].Value.ToString() + "%'" + "\n");
        }
        else if (row.Cells[4].Value.ToString().Equals("EndsWith"))
        {
            query.Append("like " + "'%" + row.Cells[5].Value.ToString() + "'" + "\n");
        }
    }

    query.Append(")" + "\n");
    return query.ToString();
}

After converting the above to Entity SQL, it looks like:将上述内容转换为 Entity SQL 后,它看起来像:

StringBuilder query = new StringBuilder();
StringBuilder query2 = new StringBuilder();

if (ComboRuleType.Text.Equals("Standard"))
{
    query.Append("select value q1 from ");
    query.Append(ComboRuleTableName.Text);
    query.Append("s");
    query.Append(" as q1 where " + "\n");
    for (int i = 0; i < dgvUpdateCriteria.RowCount; i++)
    {
        DataGridViewRow row = dgvUpdateCriteria.Rows[i];

        if (i != 0)
        {
            if (row.Cells[1].Value.ToString().Equals("AND"))
            {
                query.Append("&&" + " " + "q1." + row.Cells[3].Value.ToString());
            }
            else
            {
                query.Append("||" + " " + "q1." + row.Cells[3].Value.ToString());
            }
        }
        else
        {
            query.Append("q1." + row.Cells[3].Value.ToString());
        }

        if (row.Cells[4].Value.ToString().Equals("Contains"))
        {
            query.Append(" LIKE (" + "'%" + row.Cells[5].Value.ToString() + "%'" + ")" + "\n");
        }
        else if (row.Cells[4].Value.ToString().Equals("Equals"))
        {
            query.Append(" == (" + "'" + row.Cells[5].Value.ToString() + "'" + ")" + "\n");
        }
        else if (row.Cells[4].Value.ToString().Equals("StartsWith"))
        {
            query.Append(" LIKE (" + "'" + row.Cells[5].Value.ToString() + "%'" + ")" + "\n");
        }
        else if (row.Cells[4].Value.ToString().Equals("EndsWith"))
        {
            query.Append(" LIKE (" + "'%" + row.Cells[5].Value.ToString() + "'" + ")" + "\n");
        }
    }

    return query.ToString();
}

I construct another SQL query that contains INNER JOIN and I have looked EVERYWHERE but cannot find the equivalent translation of that SQL query to an Entity SQL query.我构造了另一个包含INNER JOIN SQL 查询,我已经查看了 EVERYWHERE,但找不到该 SQL 查询到实体 SQL 查询的等效转换。 I would really appreciate if you can help me out.如果您能帮助我,我将不胜感激。 The dynamic SQL query with INNER JOIN is as follows:带有INNER JOIN的动态 SQL 查询如下:

query.Append("SELECT * ");
query.Append("FROM [dbo].[membership] mm \n");
query.Append("INNER JOIN [dbo].[" + ComboRuleTableName.Text + "] xx \n");
query.Append("ON (mm.m_" + ComboRuleTableName.Text + "_id = xx.id) \n");
query.Append("WHERE xx.id IN ( \n");
query.Append("SELECT id from [dbo].[" + ComboRuleTableName.Text + "] \n");
query.Append("WHERE \n");
query.Append("mm.platform_name = '" + ComboRulePlatformName.Text + "' AND (\n");

for (int i = 0; i < dgvUpdateCriteria.RowCount; i++)
{
    DataGridViewRow row = dgvUpdateCriteria.Rows[i];
    if (i != 0)
    {
        query2.Append(row.Cells[1].Value.ToString() + " " + row.Cells[3].Value.ToString() + " ");
    }
    else
    {
        query2.Append(row.Cells[3].Value.ToString() + " ");
    }

    if (row.Cells[4].Value.ToString().Equals("Contains"))
    {
        query2.Append("like " + "'%" + row.Cells[5].Value.ToString() + "%'" + "\n");
    }
    else if (row.Cells[4].Value.ToString().Equals("Equals"))
    {
        query2.Append("= " + "'" + row.Cells[5].Value.ToString() + "'" + "\n");
    }
    else if (row.Cells[4].Value.ToString().Equals("StartsWith"))
    {
        query2.Append("like " + "'" + row.Cells[5].Value.ToString() + "%'" + "\n");
    }
    else if (row.Cells[4].Value.ToString().Equals("EndsWith"))
    {
        query2.Append("like " + "'%" + row.Cells[5].Value.ToString() + "'" + "\n");
    }
    else
    {
        query2.Append(" \n");
    }
}

query2.Append("))\n");
return query.Append(query2).ToString();

I NEED it to be in a string format.我需要它是字符串格式。 I later convert it from string to query format.我后来将它从字符串转换为查询格式。 I just do not know how the INNER JOIN syntax works with Entity queries.我只是不知道INNER JOIN语法如何处理实体查询。

Thank you.谢谢你。

Edit 1:编辑1:

Here is how I convert that Query into Entity Framework Object Query:以下是我将该查询转换为实体框架对象查询的方法:

                string query = EntityPreview(); //EntityPreview() is the method that gives me Raw Entity SQL Query
                var objctx = (context as IObjectContextAdapter).ObjectContext;
                if (ComboRuleTableName.Text.Equals("system"))
                {
                    ObjectQuery<system> standardList = objctx.CreateQuery<system>(query);
                    rulePreviewForm.dataGridViewCriteriaRulePreview.DataSource = standardList;
                    rulePreviewForm.Show();
                }

One of the greatest things about EntityFramework is it builds SQL for you and allows you to manipulate objects instead of SQL. EntityFramework 最伟大的事情之一是它为您构建 SQL,并允许您操作对象而不是 SQL。 There are other libraries like Dapper that are quicker when using straight SQL if you have a choice.如果您有选择,还有其他库(例如 Dapper)在使用直接 SQL 时会更快。 If you have to use EntityFramework, you would be better off writing Linq.如果必须使用 EntityFramework,最好编写 Linq。

When using Linq instead of SQL, you can still build Dynamic queries using IQueryable.当使用 Linq 而不是 SQL 时,您仍然可以使用 IQueryable 构建动态查询。 This allows you to build a query without pulling any data from the database up front.这使您无需预先从数据库中提取任何数据即可构建查询。

Without knowing much about what you are trying to do with your application, I can only offer a few tips of things to try.在不太了解您尝试使用应用程序做什么的情况下,我只能提供一些尝试的提示。 In the answer below I am making some assumptions on the naming of how you have your entities set up.在下面的答案中,我对实体设置的命名方式做了一些假设。

For getting a list of memberships from the membership table, assuming your entity for that table is called Membership:要从成员资格表中获取成员资格列表,假设该表的实体称为成员资格:

IQueryable<Membership> memberships = context.Memberships;

That is your那是你的

query.Append("SELECT * ");
query.Append("FROM [dbo].[membership] mm \n");

For your filters you will likely want to put them into a List.对于您的过滤器,您可能希望将它们放入一个列表中。

From this point on is where the dynamic part of this comes in. If you have a table for your ComboRule named [ComboRuleTable1] and another called [ComboRuleTable2], but you have to query based on input from ComboRuleTableName.Text, you can do something like this.从这一点开始,这是动态部分的用武之地。如果您有一个名为 [ComboRuleTable1] 的 ComboRule 表和另一个名为 [ComboRuleTable2] 的表,但您必须根据来自 ComboRuleTableName.Text 的输入进行查询,您可以做一些事情像这样。

var filters = new List<string>() { "name1", "name2" };

// Get which table you should join to
switch (ComboRuleTable1)
{
   // Join to tables and get filtered data
   case "ComboRuleTable1":
      memberships = memberships.ComboRuleTable1.Where(x => filters.Contains(x.PlatFormName));
      break;
   case "ComboRuleTable2":
      memberships = memberships.ComboRuleTable2.Where(x => filters.Contains(x.PlatFormName));
      break;
   default:
      break;
}

// This pulls the data from the database
var result = memberships.ToList();

Some of this will vary on how your EntityFramework is set up.其中一些会因您的 EntityFramework 的设置方式而异。

I hope this helps.我希望这有帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM