Перевод SQL запроса с INNER JOIN в Entity SQL query - C# - PullRequest
0 голосов
/ 01 апреля 2020

Я строю следующий 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();
}

После преобразования вышеупомянутого объекта в 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();
}

Я создаю еще один SQL запрос, содержащий INNER JOIN, и я смотрел ВЕЗДЕ, но не могу найти эквивалентный перевод этого SQL запроса в запрос Entity SQL. Буду очень признателен, если вы поможете мне. Динамический запрос c SQL с INNER JOIN выглядит следующим образом:

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

Мне нужно, чтобы он был в строковом формате. Позже я конвертирую его из строки в формат запроса. Я просто не знаю, как синтаксис INNER JOIN работает с запросами Entity.

Спасибо.

Edit 1:

Вот как я конвертирую этот запрос в Entity Framework Запрос объекта:

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

1 Ответ

0 голосов
/ 02 апреля 2020

Одна из главных особенностей EntityFramework - это то, что он создает для вас SQL и позволяет вам манипулировать объектами вместо SQL. Существуют и другие библиотеки, такие как Dapper, которые быстрее используют прямую SQL, если у вас есть выбор. Если вам нужно использовать EntityFramework, вам лучше написать Linq.

При использовании Linq вместо SQL вы все равно можете создавать запросы Dynami c, используя IQueryable. Это позволяет вам создавать запросы без предварительного извлечения данных из базы данных.

Не зная, что вы пытаетесь сделать со своим приложением, я могу предложить лишь несколько советов, которые можно попробовать. В ответе ниже я делаю некоторые предположения о наименовании того, как настроены ваши сущности.

Для получения списка членств из таблицы членства, предположим, что ваша сущность для этой таблицы называется Членство:

IQueryable<Membership> memberships = context.Memberships;

Это ваш

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

Для ваших фильтров вы, вероятно, захотите поместить их в список.

С этого момента и происходит динамика c отчасти это происходит. Если у вас есть таблица для вашего ComboRule с именем [ComboRuleTable1], а другая - с именем [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();

Отчасти это зависит от того, как настроена ваша EntityFramework.

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...