2014-10-29 3 views
1

В настоящее время я использую Entity Framework и вам необходимо регулярно обновлять множество объектов.Обновление пакета SQL Compact Edition

Что мне нужно сделать, это добавить номер журнала, основанный на нескольких разных таблицах. Используя SQL Server, я могу использовать хранимую процедуру с внутренними и внешними соединениями GROUP BY и ROW_NUMBER, что делает тяжелый подъем для меня, а также очень эффективным.

Смотрите код процедуры выглядит следующим образом:

CREATE PROCEDURE [dbo].[sp_UpdateNumber] 
    @RefId int 
AS 
BEGIN 
    UPDATE TableWithNumber 
    SET Nmr = other.Nmr 
    FROM (
     SELECT MIN(C.Nmr) as Nmr, Z_ID 
     FROM 
     (
      SELECT 
       ROW_NUMBER() OVER (ORDER BY D.TicksCreatedOn, D.Z_Id, D.B_ID) as Nmr, D.* 
       FROM (
        SELECT 
          S.Id as S_ID, 
          Z.Id as Z_ID, 
          B.Id as B_ID, 
          S.TicksCreatedOn 
        FROM 
          ChildTable as B 
          INNER JOIN TableWithNumber Z on Z.ChildTableRefA_Id = B.Id 
          INNER JOIN ParentTable S on Z.ParentTable_Id = S.Id 
        WHERE S.Ref_Id = @RefId 
       UNION 
        SELECT 
          S.Id as S_ID, 
          Z.Id as Z_ID, 
          B.Id as B_ID, 
          S.TicksCreatedOn 
        FROM 
          ChildTable as B 
          INNER JOIN TableWithNumber Z on Z.ChildTableRefB_Id = B.Id 
          INNER JOIN ParentTable S on Z.ParentTable_Id = S.Id 
        WHERE S.Ref_Id = @RefId) as D 
     ) as C 
    GROUP BY C.Z_ID) as other 
    WHERE other.Z_ID = Id AND Ref_Id = @RefId 
END 

Средства, хранимые процедуры не доступны в SQL Ce, а также дополнительные ограничения, как вы можете использовать GROUP BY в подразделах выбирает, я теперь рассчитать количество журналирования в коде. Я использую SqlQuery в Контексте для получения минимального требуемого набора данных, группировки его и последующего обновления для каждого объекта.

SELECT ZID 
FROM 
    (SELECT S.Id as [SID], Z.Id as [ZID], B.Id as [BID], S.TicksCreatedOn 
    FROM ChildTable AS B 
     INNER JOIN TableWithNumber as Z on Z.ChildTableRefA_Id = B.Id 
     INNER JOIN ParentTable as S on Z.ParentTable_Id = S.Id 
    WHERE S.Ref_Id = @RefId 
    UNION 
    SELECT S.Id as [SID], Z.Id as [ZID], B.Id as [BID], S.TicksCreatedOn 
    FROM ChildTable AS B 
     INNER JOIN TableWithNumber as Z on Z.ChildTableRefB_Id = B.Id 
     INNER JOIN ParentTable as S on Z.ParentTable_Id = S.Id 
     WHERE S.Ref_Id = @RefId) AS D 
ORDER BY TicksCreatedOn, ZID, BID 


     var result = Database.SqlQuery<NumberUpdate>(QUERY, new SqlCeParameter("@RefId", 1)).ToList(); 

код на приложения выглядит как этого

var grouped = result 
     .Select((x,y) => new NumberUpdate { ZID = x.ZID, Number = ++y }) 
     .GroupBy(x => x.ZID); 

    foreach (var group in grouped) 
    { 
     Database.ExecuteSqlCommand("UPDATE TableWithNumber SET Number = @Nr WHERE Id = @Id", 
      new SqlCeParameter("@Nr", group.Min(x => x.Number)), 
      new SqlCeParameter("@Id", group.Key)); 
    } 

мне было интересно, если есть более быстрый и более эффективный способ, чтобы обновить список объектов в SQL CE, чем вызов ExecuteSqlCommand в Еогеасп цикл?

+0

Единственное улучшение, которое я смог найти, - это подготовить SqlCeCommand до цикла foreach, а затем в цикле изменить значения существующих параметров. Но UPDATE очень ограничен в SQL CE. –

+0

Если вам нужны хранимые процедуры и триггеры в встраиваемой базе данных, рассмотрите [LocalDB] (http://blogs.msdn.com/b/sqlexpress/archive/2011/07/12/introducing-localdb-a-better-sql- express.aspx). –

+0

LocalDB был бы GREAT и хотел бы использовать его. Однако одним из важнейших требований нашего приложения является то, что он должен быть развернут с копированием/прошлым и не должен требовать установки установки. Поскольку LocalDB требует установки на клиенте, к сожалению, это не вариант. Еще раз, я бы ЛЮБИЛ использовать его. – UrbanEsc

ответ

0

Если ваша бизнес-логика позволяет обновлять данные в нескольких таблицах «строка за строкой» (не с помощью сложной команды SQL), вы можете попробовать «table-direct». Он включает в себя следующие шаги.

Создать SqlCeConnection объект со строкой подключения, указывающий на ваш SDF-файл. Создать SqlCeCommand объект для этого подключения с типом команды CommandType.TableDirect. Создать SqlCeResultSet с опциями ResultSetOptions.Updatable и ResultSetOptions.Scrollable.

Теперь вы можете обновлять строки таблицы с помощью Seek, Read и Update методы. Этот подход, возможно, является самым быстрым способом. Но для этого требуется написать гораздо больше кода, чем традиционный подход EF.

Смежные вопросы