Как реализовать SQL движок в своём приложении?

Есть необходимость привязать возможность использования SQL запросов для "работы" с данными в приложении на C#.
Данные лежат в памяти приложения в виде POCO объектов в списках, словарях и остальных ICollection'ах.
Нашёл библиотеку sql-dotnet которая:
  1. Парсит SQL и гренерирует Execution plan в виде IL-like кода
  2. SQLRuntime который выполняет IL-like код вызывая пользовательскую реализацию IQueryExecutor'а
  3. Интерфейс IQueryExecutor, реализуя который мы "предоставляем" доступ к данным

Данная библиотека достаточно сырая и не поддерживает много чего из ANSI SQL, но допилить можно.

65152e82b00cc756916002.jpeg
Скриншот фрагмента кода удалён модератором.

Реализация IQueryExecutor:
internal class Executor : IQueryExecutor
 {
     private void AssertFunction(string name, IList<QueryParameter> parameter, int minParameter, int maxParameter, DataType[] types)
     {
         if (parameter.Count > maxParameter || parameter.Count < minParameter)
         {
             throw new ArgumentException(string.Format("`{0}` expected at least {1} parameter.", name, minParameter));
         }
     }

     public Tuple<object, DataType> CallFunction(string name, IList<QueryParameter> parameter)
     {
         name = name.ToLower();
         if (!string.IsNullOrWhiteSpace(name))
         {
             switch (name)
             {
                 #region [Concat]
                 case "concat":
                     {
                         if (parameter == null || parameter.Count < 1)
                         {
                             throw new ArgumentException("`Concat` requires atleast one argument.");
                         }

                         StringBuilder sb = new StringBuilder();
                         foreach (var p in parameter)
                         {
                             sb.Append(p.Value);
                         }
                         return new Tuple<object, DataType>(sb.ToString(), DataType.Str);
                     }
                 #endregion

                 #region [newid]
                 case "newid":
                     {
                         AssertFunction(name, parameter, 0, 0, new DataType[] { });

                         return new Tuple<object, DataType>(Guid.NewGuid(), DataType.Object);
                     }
                     #endregion
             }
         }

         throw new Exception("Could not find function " + name ?? "--noname--");
     }

     public TableDefinition GetTableSchema(string owner, string table) { ... }

     public int Insert(string tableName, IList<string> columns, IList<QueryParameter> parameter) { ... }

     public IList<QueryResultRow> Select(string tableName, bool isScalar, bool distinctValues, IList<ColumnDefinition> columns, FilterCursorCCNode filter, Scope parameter)
     {
         var returnValue = new List<QueryResultRow>();
         var row = new QueryResultRow();
         row.Columns.Add("archiv_guid", Guid.NewGuid());
         row.Columns.Add("archiv_blob", new byte[] { 1, 23, 213, 24 });
         returnValue.Add(row);
         return returnValue;
     }
 }


Вопрос: Существует ли более зрелое подобное решение, которое позволит прикрутить SQL к своему проекту?
  • Вопрос задан
  • 387 просмотров
Решения вопроса 1
AshBlade
@AshBlade Куратор тега C#
Просто хочу быть счастливым
1. GraphQL - специальный язык запросов. Можно изменять/обновлять/добавлять/читать. Есть полноценный пакет, который парсит запрос и выполняет его. Можно к In memory коллекциям подкрутить. Но это не SQL

2. OData - тоже язык запросов. Можно изменять/добавлять/читать/удалять. Он достаточно старый и разобраться сложнее. Тоже есть фреймворк, который автоматизирует работу по парсингу/выполнению. Это также не SQL

3. In Memory sqlite - можно запустить SQLite в памяти и проксировать запросы уже ему.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
firedragon
@firedragon
Не джун-мидл-сеньор, а трус-балбес-бывалый.
Что я не пойму целей.
На скринах видна управляющая панель типа дерева запросов.
Если вам нужны просто результаты то используйте
LINQ прекрасно работает по всем обьектам.
Или https://learn.microsoft.com/en-us/ef/core/provider...
или sqlite https://learn.microsoft.com/ru-ru/dotnet/standard/...
Ответ написан
BasiC2k
@BasiC2k
.NET developer (open to job offers)
Может я не до конца понимаю задачу, но в EF есть FromSqlRaw , который позволяет выполнить текстовый SQL запрос.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы