Гость
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / Entity Framework + INSTEAD OF INSERT trigger + update action / 16 сообщений из 16, страница 1 из 1
27.02.2013, 12:47
    #38167837
HiTechAnarxi
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Entity Framework + INSTEAD OF INSERT trigger + update action
Есть таблица

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
CREATE TABLE [TradingData].[Security](
	[Id] [int] IDENTITY(1,1) NOT NULL,
	[Isin] [varchar](20) NOT NULL,
	[Ric] [varchar](20) NOT NULL,
	[Mic] [varchar](20) NULL,
	[Sedol] [varchar](20) NULL,
	[BftId] [int] NULL,
	[Name] [nvarchar](max) NULL,
	[LongName] [nvarchar](max) NULL,
	[ClassId] [int] NULL,
	[CurrencyId] [int] NULL,
	[EconomicSectorId] [int] NULL,
	[CountryId] [int] NOT NULL,
	[ParentId] [int] NULL,
	[ParentIdentify] [varchar](20) NULL,
	[ParentIdentifyType] [varchar](20) NULL,
 CONSTRAINT [PK_Security] PRIMARY KEY CLUSTERED 
(
	[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]



в ней есть такой вот тригер

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
CREATETRIGGER [TradingData].[IT_Security] ON [TradingData].[Security] INSTEAD OF INSERT AS
BEGIN
SET NOCOUNT OFF;

merge into [TradingData].[Security] as T
using inserted as i
on LOWER(T.Isin)= LOWER(i.Isin) OR  LOWER(T.Ric) = LOWER(i.Ric) OR  LOWER(T.Sedol) = LOWER(i.Sedol) OR  LOWER(T.Sedol) = LOWER(i.Sedol)

when matched then 
update set 
	T.Mic=i.Mic,
	T.Isin=i.Isin,
	T.Sedol=i.Sedol,
	T.Ric=i.Ric,
	T.Name=i.Name,
	T.LongName=i.LongName,
	T.ClassId=i.ClassId,
	T.CurrencyId=i.CurrencyId,
	T.EconomicSectorId=i.EconomicSectorId,
	T.CountryId=i.CountryId,
	T.ParentId=i.ParentId

when not matched then
INSERT
		(Isin,Ric,Sedol,Mic,BftId,Name,LongName,ClassId,CurrencyId,EconomicSectorId,CountryId,ParentId,ParentIdentify,ParentIdentifyType)
VALUES
		(i.Isin,i.Ric,i.Sedol,Mic,i.BftId,i.Name,i.LongName,i.ClassId,i.CurrencyId,i.EconomicSectorId,i.CountryId,i.ParentId,i.ParentIdentify,i.ParentIdentifyType);

select Id from  [TradingData].[Security] where @@ROWCOUNT > 0 and Id = scope_identity();
End



С тригера понятно что при инсерте делается проверка по нескольким ключам и если есть совпадение делается апдейт вместо инсерт

При работе через Entity Framework при попытке инсерта данные которые отвечают условиям тригера вываливается ошибка

The element at index 0 in the collection of objects to refresh is in the added state. Objects in this state cannot be refreshed.

есть идеи как можно обойти проверку на данные которые он пытается вставить а точнее отключить проверку?
...
Рейтинг: 0 / 0
27.02.2013, 12:51
    #38167845
HiTechAnarxi
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Entity Framework + INSTEAD OF INSERT trigger + update action
не та ошибка простите,

вот правильная

Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries.
...
Рейтинг: 0 / 0
27.02.2013, 13:16
    #38167897
buser
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Entity Framework + INSTEAD OF INSERT trigger + update action
1. Судя по телу триггера база не заточена на работу с ней к.л. другого приложения...
2. Триггер нах.
3. Ваш мердж не изменил ни одной записи... ?
4. select в триггере - это 3.14здец
Может я что-то забыл...
5. не стоит размазывать логику между базой и клиентом... т.е. иногда без этого ни как, но, в любом случае, делать это нужно аккуратно.
P.S.: это мнение дилетанта... т.е. это набор мыслей что пронеслись бы в моей голове увидь я этот код в первый раз... до начала детального разбирательства...
...
Рейтинг: 0 / 0
27.02.2013, 13:22
    #38167914
HiTechAnarxi
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Entity Framework + INSTEAD OF INSERT trigger + update action
buser1. Судя по телу триггера база не заточена на работу с ней к.л. другого приложения...
2. Триггер нах.
3. Ваш мердж не изменил ни одной записи... ?
4. select в триггере - это 3.14здец
Может я что-то забыл...
5. не стоит размазывать логику между базой и клиентом... т.е. иногда без этого ни как, но, в любом случае, делать это нужно аккуратно.
P.S.: это мнение дилетанта... т.е. это набор мыслей что пронеслись бы в моей голове увидь я этот код в первый раз... до начала детального разбирательства...

1. Я так и не понял что вы пытались сказать
2. Если бы можно было Нах то так бы и сделал
3. Изменил но вопрос не в том
4. Это необходимость для ЕФ
5. Если вопрос стоит так что для поверки существующих данных придется перетянуть 800 000 рекордов то стоит (и это для малой базы)
...
Рейтинг: 0 / 0
27.02.2013, 14:11
    #38168022
buser
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Entity Framework + INSTEAD OF INSERT trigger + update action
А Вы можете запустить профайлер и посмотреть на трассу при update?
...
Рейтинг: 0 / 0
27.02.2013, 14:12
    #38168025
buser
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Entity Framework + INSTEAD OF INSERT trigger + update action
Т.е. insert
...
Рейтинг: 0 / 0
27.02.2013, 15:06
    #38168127
buser
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Entity Framework + INSTEAD OF INSERT trigger + update action
P.S.: попробуйте переписать триггер... т.е. избавтесь от
select Id from [TradingData].[Security] where @@ROWCOUNT > 0 and Id = scope_identity();
Заменив на output во времянку с финальным селектом из нее же...
...
Рейтинг: 0 / 0
27.02.2013, 21:55
    #38168735
Lord British
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Entity Framework + INSTEAD OF INSERT trigger + update action
автор, EF не читан.

то что сыпется в бд при insertexec sp_executesql N'insert [dbo].[Security]([Isin], [Ric], [Mic], [Sedol], [BftId], [Name], [LongName], [ClassId], [CurrencyId], [EconomicSectorId], [CountryId], [ParentId], [ParentIdentify], [ParentIdentifyType])
values (@0, @1, null, null, null, null, null, null, null, null, @2, null, null, null)
select [Id]
from [dbo].[Security]
where @@ROWCOUNT > 0 and [Id] = scope_identity()',N'@0 varchar(20),@1 varchar(20),@2 int',@0='zzz',@1='qweqw',@2=1


обрати внимание на scope_identity() в этой кучке букв оно возвратит NULL на втором вызове savechanges если сделать последовательно

var z = new Security() { Isin = "234t", Ric = "23t", CountryId = 21 };

ctx.Security.Add(z);

ctx.SaveChanges();

ctx.Security.Add(z);

ctx.SaveChanges();

EF решает что ничего вставлено не было. и говорит тебе об этом.

кстати, даже если его заменить каким-то перцем на @@identity работать оно в приведенной последовательности команд не будет.

var z = new Security() { Isin = "234t", Ric = "23t", CountryId = 21 };

ctx.Security.Add(z); // в identity map нет обьекта с ключем по умолчанию для создаваемых обьектов

ctx.SaveChanges(); // теперь он в identity map со сгенеренным ключем.

ctx.Security.Add(z); // тут ошибка будет т. к. в identity map будет существовать обьект с таким ключемю

ctx.SaveChanges();

--
схему переделывать. EF по разному ведет себя в случае insert/update/delete а вы взяли и сделали не то чего он ожидает. можно сделать на хранимках требуемое.
...
Рейтинг: 0 / 0
06.01.2014, 02:42
    #38518277
Басим
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Entity Framework + INSTEAD OF INSERT trigger + update action
HiTechAnarxi,

Нужно вернуть для EF inserted.id

вставьте в insert после перечисления колонок следующую красную строчку:

INSERT
(Isin,Ric,Sedol,Mic,BftId,Name,LongName,ClassId,CurrencyId,EconomicSectorId,CountryId,ParentId,ParentIdentify,ParentIdentifyType)

OUTPUT INSERTED.Id

select Id from [TradingData].[Security] where @@ROWCOUNT > 0 and Id = scope_identity();
...
Рейтинг: 0 / 0
23.07.2014, 17:46
    #38704193
Andrey1306
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Entity Framework + INSTEAD OF INSERT trigger + update action
Такая же проблема, какое было решение в Вашем случае

EF генерит такой запрос

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
exec sp_executesql N'INSERT [dbo].[Request]([RequestNumber], [CreateUserID], [CreateDate], [ModifyUserID], [ModifyDate], [RequestTypeID], 
[RequestTypeAdditional], [RegionID], [StreetID], [HouseID], [House], [Korpus], [Flat], [Podezd], [Floor], [code], [Entrance], [DriveFrom], 
[Organization], [Caller], [Phone], [BossID], [CarID], [IsMade], [isClosed], [Request_OldID], [isPassed], [Time_Departure], [Time_Arrive], 
[Time_Finish], [Time_Back], [ResultText], [FeggID], [TM_Organisation], [TM_Phone], [TM_text], [isDelete])
VALUES (@0, @1, @2, @3, @4, @5, NULL, @6, @7, @8, @9, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @10, @11,
 NULL, @12, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL)
SELECT [RequestID], [dt_Year]
FROM [dbo].[Request]
WHERE @@ROWCOUNT > 0 
AND [RequestID] = scope_identity()',
N'@0 int,@1 int,@2 datetime2(7),@3 int,@4 datetime2(7),@5 int,@6 int,@7 int,@8 int,@9 nvarchar(10),@10 bit,@11 bit,@12 bit',
@0=0,@1=3,@2='2014-07-23 15:43:42.7724513',@3=3,@4='2014-07-23 15:43:42.7724513',@5=18,@6=1,@7=35261,@8=36008,@9=N'67',@10=0,@11=0,@12=0



если выполнять его "вручную" все работает, EF 6 выдает

Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries.
...
Рейтинг: 0 / 0
23.07.2014, 21:16
    #38704325
kmaw
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Entity Framework + INSTEAD OF INSERT trigger + update action
а зачем кусать кактус?
...
Рейтинг: 0 / 0
23.07.2014, 21:20
    #38704330
Andrey1306
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Entity Framework + INSTEAD OF INSERT trigger + update action
kmaw,

Это длинная история

начиналась она тут
...
Рейтинг: 0 / 0
23.07.2014, 21:22
    #38704333
kmaw
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Entity Framework + INSTEAD OF INSERT trigger + update action
Andrey1306kmaw,

Это длинная история

начиналась она тут

тогда можно было это реализовать, забив на мейнстрим. давно
...
Рейтинг: 0 / 0
23.07.2014, 21:26
    #38704336
Andrey1306
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Entity Framework + INSTEAD OF INSERT trigger + update action
kmawAndrey1306kmaw,

Это длинная история

начиналась она тут

тогда можно было это реализовать, забив на мейнстрим. давно

Подскажите как ?
...
Рейтинг: 0 / 0
24.07.2014, 01:34
    #38704412
gandjustas
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Entity Framework + INSTEAD OF INSERT trigger + update action
HiTechAnarxiС тригера понятно что при инсерте делается проверка по нескольким ключам и если есть совпадение делается апдейт вместо инсерт

При работе через Entity Framework при попытке инсерта данные которые отвечают условиям тригера вываливается ошибка

Вот я пытаюсь представить как это выглядит на стороне приложения:
1) Приходит некоторый сигнал с набором параметров
2) открывается контекст EF
3) в него добавляется новый объект, полям присваиваются параметры
4) делается SaveChanges, чтобы отправить insert в базу
5) В триггере insert заменяется на апдейт из-за этого EF ломается ибо на insert он ожидает добавление объекта.

Внимание вопрос, зачем тут EF и мапинг на объекты? Сделайте процедуру, которая делает "upsert", дергайте её через DbContext.Database.ExecuteSqlCommand, тогда все ваше приложение будет выгладеть так:
1) Приходит некоторый сигнал с набором параметров
2) Открывается контекст EF
3) Вызывается процедура
4) Процедура делает upsert

И триггеры, особенно такие нетривиальные, не нужны.
...
Рейтинг: 0 / 0
24.07.2014, 14:11
    #38704949
Andrey1306
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Entity Framework + INSTEAD OF INSERT trigger + update action
gandjustas,

все решилось, вместо триггера
Код: sql
1.
INSTEAD OF  INSERT  

переделал на
Код: sql
1.
AFTER  INSERT
...
Рейтинг: 0 / 0
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / Entity Framework + INSTEAD OF INSERT trigger + update action / 16 сообщений из 16, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]