Linq To Sql дублирует строку в случае обновления

#c# #linq #duplicates #datarow

#c# #linq #дубликаты #поток данных

Вопрос:

У меня есть один объект, который всегда дублирует строку, когда ее нужно обновить:

     protected static Task RegisterToDisc(Task task)
    {         
        try
        {
            using (DataContext context = new DataContext())
            {
                //this will print an actual existing id from the db
                _log.Debug(task.ID);

                context.Tasks.InsertOnSubmit(task);
                context.SubmitChanges();
            }
        }
        catch(Exception e)
        {
           //...
        }
        return task;
    }
  

Когда я печатаю идентификатор перед сохранением, он фактически выводит идентификатор, который действительно существует в БД.

это таблица:

 CREATE TABLE [dbo].[TaskSet](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [Message] [nvarchar](max) NOT NULL,
    [Result] [nvarchar](max) NOT NULL,
    [Status] [int] NOT NULL,
    [Priority] [int] NOT NULL,
    [Name] [nvarchar](max) NOT NULL,
    [DateTimeAsked] [datetime] NOT NULL,
    [DateTimePerfomed] [datetime] NOT NULL,
    [SessionID] [nvarchar](max) NOT NULL,
 CONSTRAINT [PK_TaskSet] 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]

GO
  

Редактировать

Задача task уже отправляется из базы данных.Идентификатор содержит a number , который существует в базе данных, почему Linq вставляет объект с PK, который не равен null и уже находится в БД.

в java hibernate вы neet context.insertOrUpdate(task); , и он решит, что делать с помощью первичного ключа.

Комментарии:

1. откуда берется ваша «задача», прежде чем вы перейдете к этому методу?

Ответ №1:

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

 var objToUpdate = context.Tasks.SingleOrDefault(x=>x.Id == Id);
objToUpdate.Property1 = "updated value";
objToUpdate.Property2 = "updated value";
//do it for all properties that need updating
context.SubmitChanges();//since the object is tracked by context it will automatically generate sql to reflect update in db
  

Комментарии:

1. если задача поступает из базы данных, просто вызовите context.SubmitChanges , но здесь это не принесет вам никакой пользы, потому что вы создаете новый контекст данных при попытке обновить объект. поток таков: получить объект из контекста, внести в него изменения, а затем вызвать SubmitChanges тот же контекст , который использовался для извлечения объекта из БД

2. Спасибо, я отправил контекст в качестве параметра.