«Ошибка автосинхронизации пользователя» с использованием TPT, просмотр и вместо триггера вставки - PullRequest
1 голос
/ 02 июня 2011

Попытка использовать Linq2SQL с наследованием классов с использованием шаблона TPT, подобного этому http://blogs.msdn.com/sbajaj/archive/2008/04/02/tpt-with-linq-to-sql.aspx

Пример приложения работает нормально. Вот мой код:

Таблицы и просмотры:

CREATE TABLE [dbo].[social_event](
    [Id] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY,
    [Creator] [uniqueidentifier] NOT NULL FOREIGN KEY REFERENCES [dbo].[aspnet_Users](UserId),
    [EventDate] [datetime] NOT NULL)
GO

CREATE TABLE [dbo].[social_addfriendevent](
    [ID] [int] NOT NULL PRIMARY KEY FOREIGN KEY REFERENCES [dbo].[social_event](Id),
    [Friend] [uniqueidentifier] NOT NULL FOREIGN KEY REFERENCES [dbo].[aspnet_Users](UserId),
    [Added] [bit] NOT NULL DEFAULT((0)))
GO

CREATE VIEW [dbo].[event]
AS
SELECT t0.Id, t0.Creator, t0.EventDate, t1.Friend, t1.Added, 'AddFriendEvent' AS EventType
FROM  dbo.social_event AS t0 INNER JOIN
   dbo.social_addfriendevent AS t1 ON t0.Id = t1.Id
GO

Мой триггер "Вместо вставки":

CREATE TRIGGER [dbo].[trigger_update_event] ON [dbo].[event] INSTEAD OF INSERT
AS
    DECLARE @rc AS INT;
    SET @rc = @@ROWCOUNT;
    IF @rc = 0 RETURN;

    DECLARE @Id AS INT
    DECLARE @EventType AS NVARCHAR(50)
    DECLARE @Creator AS uniqueidentifier
    DECLARE @EventDate AS datetime
    DECLARE @Friend AS uniqueidentifier
    DECLARE @Added AS bit 

    IF @rc = 1
        BEGIN
            SELECT @Id=Id,
   @EventType=EventType,
                 @Creator=Creator,
                 @EventDate = getdate(),
                 @Friend=Friend,
                 @Added=Added
            FROM INSERTED

            INSERT INTO dbo.social_event VALUES(@Creator, @EventDate)
            SELECT @Id = SCOPE_IDENTITY()
            IF @EventType = 'AddFriendEvent'
                INSERT INTO dbo.social_addfriendevent VALUES(@Id, @Friend, @Added)                            
        END
    ELSE
        BEGIN
            DECLARE cursor_inserted CURSOR FAST_FORWARD FOR
                SELECT EventType,
                     Creator,
                     EventDate,
                     Friend,
                     Added
                FROM INSERTED
            OPEN cursor_inserted;

            FETCH NEXT FROM cursor_inserted INTO @EventType,
                                             @Creator,
                                             @EventDate,
                                             @Friend,
                                             @Added;
            WHILE @@FETCH_STATUS = 0
            BEGIN
                INSERT INTO dbo.social_event VALUES(@Creator, @EventDate)
                SELECT @Id = SCOPE_IDENTITY()                
                IF @EventType = 'AddFriendEvent'
                INSERT INTO dbo.social_addfriendevent VALUES(@Id, @Friend, @Added)
            END
            CLOSE cursor_inserted;
            DEALLOCATE cursor_inserted;
        END

Мои классы данных с сопоставлениями:

[InheritanceMapping(Code = "AddFriendEvent", Type = typeof(AddFriendEvent), IsDefault = true)]
 [Table(Name = "dbo.event")]
 public abstract class Event
 {
 private static int s_id;

 public Event()
 {
  this.Id = --Event.s_id;
 }

 public Event(string eventType)
  : this()
 {
  EventType = eventType;
 }

 [Column(IsPrimaryKey = true)]
 public int Id;

 [Column(Name = "Creator")]
 public Guid CreatorId;

 [Column(Name = "EventDate", DbType = "datetime")] 
 public DateTime Date;

 [Column(IsDiscriminator = true, Name = "EventType")]
 public string EventType;
 }

 public class AddFriendEvent : Event
 {
 [Column(Name = "Added", CanBeNull = false)]
 public bool Added;

 [Column(Name = "Friend", CanBeNull = false)]
 public Guid Friend;

 public AddFriendEvent()
  : base("AddFriendEvent")
 {
 }
 }

Когда я пытаюсь создать новый AddFriendEvent и сохранить его в базе данных, как здесь:

DataContext dc = new DataContext(connectionString);
   Table<Event> allEvents = dc.GetTable<Event>();
   AddFriendEvent ev = new AddFriendEvent()
   {
    Added = true,
    CreatorId = Guid.Parse("379959D-58FE-4A57-BB02-559E3E855B8F"),
    Date = DateTime.Now,
    Friend = Guid.Parse("379959D-58FE-4A57-BB02-559E3E855B8F")
   };
   allEvents.InsertOnSubmit(ev);
   dc.SubmitChanges();

Я получил «Ошибка автосинхронизации пользователя» . Что не так?


Ответы [ 3 ]

1 голос
/ 02 июня 2011

В настоящее время у меня и моего друга тоже была такая же проблема.Это связано с запросом, сгенерированным LinqtoSQL.Всякий раз, когда вы вставляете против просмотра, используя проблему триггера, возникает b'coz scope_identity, используемый linq to sql.

Возвращает @ID из триггера, наконец, что вам нужно.B'coz, если не сделать этого, он возвращает NULL, и это вызывает проблему.

0 голосов
/ 10 июля 2015

У меня была похожая проблема, и я хотел поделиться своим решением, так как отладка заняла у меня почти шесть часов.

Оказывается, что один из моих AFTER INSERT SQL-триггеров вызывал это System.InvalidOperationException : Member AutoSync исключение, но при вставке той же записи в SSMS не возникало ошибок.

Вот фрагмент кода триггера, который вызывал проблемы:

DECLARE someCursor CURSOR FOR SELECT someIntValue FROM someTable
WHERE someColumn = 1

OPEN someCursor

WHILE (1 = 1)
BEGIN
    FETCH NEXT FROM someCursor

    IF (@@FETCH_STATUS <> 0)
    BREAK

    // For each row, insert into another table
    INSERT INTO AnotherTable (Column1, Column2) VALUES (3,4)
END
CLOSE someCursor
DEALLOCATE someCursor

Строка проблемы была FETCH NEXT FROM someCursor - я не использовал ключевое слово INTO, которое для документации MSDN SQL не требуется.

Поэтому я изменил свой код на это, и мое исключение AutoSync исчезло.

DECLARE @localVariable int

DECLARE someCursor CURSOR FOR SELECT someIntValue FROM someTable
WHERE someColumn = 1

OPEN someCursor

WHILE (1 = 1)
BEGIN
    FETCH NEXT FROM someCursor INTO @localVariable // MUST ADD THIS

    IF (@@FETCH_STATUS <> 0)
    BREAK

    // For each row, insert into another table
    INSERT INTO AnotherTable (Column1, Column2) VALUES (3,4)
END
CLOSE someCursor
DEALLOCATE someCursor

Надеюсь, это поможет кому-то по дороге с той же проблемой, что и у меня.

0 голосов
/ 16 ноября 2011

Спасибо, это помогло мне найти проблему. По сути, не используйте какие-либо выборки для разных таблиц в вашем триггере. Даже если вы это сделаете, просто присвойте значения выбора некоторым переменным, объявленным в триггере, что должно решить проблему. * 1001 например *

        SELECT TOP 1
                @accountStart = def.AccountNoStart, 
                @accountEnd = def.AccountNoEnd,
                @barcode = I.Barcode
        FROM HSBarCodeDefinition def
        INNER JOIN INSERTED I ON def.BarcodeLength = LEN(I.Barcode)     

Идентификатор испорчен, и это то, что вызывает все проблемы.

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