Можно ли запустить родной sql с сущностью Framework? - PullRequest
65 голосов
/ 27 мая 2009

Я пытаюсь найти поле XML в таблице. Это не поддерживается EF.

Без использования чистого Ado.net можно иметь встроенную поддержку SQL с EF?

Ответы [ 7 ]

72 голосов
/ 16 октября 2009

Для .NET Framework версии 4 и выше: используйте ObjectContext.ExecuteStoreCommand(), если ваш запрос не возвращает результатов, и используйте ObjectContext.ExecuteStoreQuery, если ваш запрос возвращает результаты.

Для предыдущих версий .NET Framework приведен пример, иллюстрирующий, что делать. Замените ExecuteNonQuery (), если необходимо, если ваш запрос возвращает результаты.

static void ExecuteSql(ObjectContext c, string sql)
{
    var entityConnection = (System.Data.EntityClient.EntityConnection)c.Connection;
    DbConnection conn = entityConnection.StoreConnection;
    ConnectionState initialState = conn.State;
    try
    {
        if (initialState != ConnectionState.Open)
            conn.Open();  // open connection if not already open
        using (DbCommand cmd = conn.CreateCommand())
        {
            cmd.CommandText = sql;
            cmd.ExecuteNonQuery();
        }
    }
    finally
    {
        if (initialState != ConnectionState.Open)
            conn.Close(); // only close connection if not initially open
    }
}
24 голосов
/ 01 октября 2012

Используя Entity Framework 5.0, вы можете использовать ExecuteSqlCommand для выполнения многострочных / многокомандных операторов SQL. Таким образом, вам не нужно предоставлять какой-либо вспомогательный объект для хранения возвращаемого значения, поскольку метод возвращает int (результат, возвращаемый базой данных после выполнения команды).

Пример:

context.Database.ExecuteSqlCommand(@
"-- Script Date: 10/1/2012 3:34 PM  - Generated by ExportSqlCe version 3.5.2.18
SET IDENTITY_INSERT [Students] ON;

INSERT INTO [Students] ([StudentId],[FirstName],[LastName],[BirthDate],[Address],[Neighborhood],[City],[State],[Phone],[MobilePhone],[Email],[Enrollment],[Gender],[Status]) VALUES (12,N'First Name',N'SecondName',{ts '1988-03-02 00:00:00.000'},N'RUA 19 A, 60',N'MORADA DO VALE',N'BARRA DO PIRAÍ',N'Rio de Janeiro',N'3346-7125',NULL,NULL,{ts '2011-06-04 21:25:26.000'},2,1);

INSERT INTO [Students] ([StudentId],[FirstName],[LastName],[BirthDate],[Address],[Neighborhood],[City],[State],[Phone],[MobilePhone],[Email],[Enrollment],[Gender],[Status]) VALUES (13,N'FirstName',N'LastName',{ts '1976-04-12 00:00:00.000'},N'RUA 201, 2231',N'RECANTO FELIZ',N'BARRA DO PIRAÍ',N'Rio de Janeiro',N'3341-6892',NULL,NULL,{ts '2011-06-04 21:38:38.000'},2,1);
");

Подробнее об этом см. Здесь: Entity Framework Code First: выполнение файлов SQL при создании базы данных

17 голосов
/ 16 марта 2013

Для Entity Framework 5 использование context.Database.SqlQuery.

А для Entity Framework 4 использовать context.ExecuteStoreQuery следующий код:

 public string BuyerSequenceNumberMax(int buyerId)
    {
        string sequenceMaxQuery = "SELECT TOP(1) btitosal.BuyerSequenceNumber FROM BuyerTakenItemToSale btitosal " +
                                  "WHERE btitosal.BuyerID =  " + buyerId +
                                  "ORDER BY  CONVERT(INT,SUBSTRING(btitosal.BuyerSequenceNumber,7, LEN(btitosal.BuyerSequenceNumber))) DESC";

        var sequenceQueryResult = context.Database.SqlQuery<string>(sequenceMaxQuery).FirstOrDefault();

        string buyerSequenceNumber = string.Empty;

        if (sequenceQueryResult != null)
        {
            buyerSequenceNumber = sequenceQueryResult.ToString();
        }

        return buyerSequenceNumber;
    }

Чтобы вернуть список, используйте следующий код:

 public List<PanelSerialList> PanelSerialByLocationAndStock(string locationCode, byte storeLocation, string itemCategory, string itemCapacity, byte agreementType, string packageCode)
 {
       string panelSerialByLocationAndStockQuery = "SELECT isws.ItemSerialNo,  im.ItemModel " +
        "FROM Inv_ItemMaster im   " +
        "INNER JOIN  " +
        "Inv_ItemStockWithSerialNoByLocation isws  " +
        "   ON im.ItemCode = isws.ItemCode   " +
        "       WHERE isws.LocationCode = '" + locationCode + "' AND  " +
        "   isws.StoreLocation = " + storeLocation + " AND  " +
        "   isws.IsAvailableInStore = 1 AND " +
        "   im.ItemCapacity = '" + itemCapacity + "' AND " +
        "   isws.ItemSerialNo NOT IN ( " +
        "           Select sp.PanelSerialNo From Special_SpecialPackagePriceForResale sp  " +
        "           Where sp.PackageCode = '" + packageCode + "' )";


    return context.Database.SqlQuery<PanelSerialList>(panelSerialByLocationAndStockQuery).ToList();


}
16 голосов
/ 08 января 2012

Начиная с .NET 4 вы можете использовать ExecuteStoreQuery метод:

var list = myDBEntities.ExecuteStoreQuery<MyClass>(MyClass.sql);

где myDBEntities наследуется от ObjectContext.

class MyClass
{
    /* You can change query to more complicated, e.g. with joins */
    public const string sql = @"select [MyTable].[MyField] from [MyTable]";
    public string MyField { get; set; }
}

Обратите внимание, что MyTable - это реальное имя таблицы, а не класс EF.

3 голосов
/ 19 апреля 2013

Не усложняйте

using (var context = new MyDBEntities())
{
    var m = context.ExecuteStoreQuery<MyDataObject>("Select * from Person", string.Empty);
    //Do anything you wonna do with 
    MessageBox.Show(m.Count().ToString());
}
2 голосов
/ 05 октября 2010
public class RaptorRepository<T>
    where T : class
{
    public RaptorRepository()
        : this(new RaptorCoreEntities())
    {
    }

    public RaptorRepository(ObjectContext repositoryContext)
    {
        _repositoryContext = repositoryContext ?? new RaptorCoreEntities();
        _objectSet = repositoryContext.CreateObjectSet<T>();
    }

    private ObjectContext _repositoryContext;
    private ObjectSet<T> _objectSet;
    public ObjectSet<T> ObjectSet
    {
        get
        {
            return _objectSet;
        }
    }


    public void DeleteAll()
    {
        _repositoryContext
            .ExecuteStoreCommand("DELETE " + _objectSet.EntitySet.ElementType.Name);
    }
}
0 голосов
/ 06 января 2017

Так что же мы скажем обо всем этом в 2017 году? Консультации 80k предполагают, что запуск SQL-запроса в EF - это то, что многие люди хотят делать. Но почему? Для чего?

Джастин, гуру с 20-кратной репутацией, в принятом ответе дает нам статический метод, который выглядит как строка за строкой, как эквивалентный код ADO. Обязательно хорошо скопируйте, потому что есть несколько тонкостей, чтобы не ошибиться. И вы обязаны объединить ваш запрос с вашими параметрами времени выполнения, так как нет никаких условий для правильных параметров. Таким образом, все пользователи этого метода будут создавать свои SQL с помощью строковых методов (хрупкие, непроверяемые, инъекции SQL), и ни один из них не будет модульным тестированием.

Другие ответы имеют те же недостатки, только более того. SQL похоронен в двойных кавычках. Возможности SQL-инъекций широко распространены. Уважаемые сверстники, это абсолютно дикое поведение. Если бы это был C # генерируемый, была бы война пламени. Мы даже не принимаем генерацию HTML таким образом, но как-то нормально для SQL. Я знаю, что параметры запроса не были предметом вопроса, но мы копируем и повторно используем то, что видим, и ответы здесь являются и моделями, и свидетельством того, что делают люди.

EF растопил наш мозг? EF не хочет, чтобы вы использовали SQL, поэтому зачем использовать EF для SQL.

Желание использовать SQL для общения с реляционной БД является здоровым, нормальным импульсом для взрослых. QueryFirst показывает, как это можно сделать разумно, ваш файл sql в .sql, проверенный при вводе, с intellisense для таблиц и столбцов. Оболочка C # генерируется инструментом, поэтому ваши запросы становятся доступными для обнаружения в коде, а также для ваших входных данных и результатов. Строгая типизация без необходимости беспокоиться о типе. Нет необходимости запоминать имя столбца или его индекс. И есть множество других преимуществ ... Соблазн для объединения удален . Возможность неправильного обращения с вашими подключениями также. Все ваши запросы и код, который обращается к ним, постоянно тестируются на интеграцию с вашей БД разработчика. Изменения схемы в вашей БД появляются как ошибки компиляции в вашем приложении. Мы даже генерируем метод самопроверки в оболочке, поэтому вы можете проверять новые версии вашего приложения на существующие производственные базы данных, не дожидаясь звонка телефона. Кому-нибудь еще нужно убедить?

Отказ от ответственности: я написал QueryFirst: -)

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