Updating an object using Linq-to-SQL - adding an object that is not new

I am trying to write a program that uses Linq-to-SQL to interact with a database (MS SQL Server 2008). Adding and removing seem ok, but I can't plunge into updates.

The object has a version column on it, which is the timestamp column in the database and is used for the optimistic lock that is built into Linq-to-SQL. I set the Update Check property for all fields on the Never object.

I have the following SaveTaskCommand, which is used to insert and update entities, depending on whether a specific task has already been added to the database.

public class SaveTaskCommand : CustomCommand
{
    private Task _task;
    private TaskDetailsViewModel _taskDetails;

    public SaveTaskCommand(Task task, TaskDetailsViewModel taskDetails)
    {
        _task = task;
        _taskDetails = taskDetails;
    }

    public override void Execute(object parameter)
    {
        TaskRepository taskRepository = new TaskRepository();
        if (!taskRepository.ContainsTask(_task))
        {
            taskRepository.AddTask(_task);
            _taskDetails.Mediator.NotifyColleagues(ViewModelMessages.TaskAdded, 
                _task);
        }
        else
        {
            taskRepository.UpdateTask(_task);
            _taskDetails.Mediator.NotifyColleagues(
                ViewModelMessages.TaskAmended, null);
        }
    }

    public override bool CanExecute(object parameter)
    {
        return _task.IsValid();
    }
}

CustomCommand - , ICommand CanExecuteChanged, .

, TaskRepository Execute() , , , , . TaskRepository .

public class TaskRepository : IRepository
{
    private DataContextDataContext _dataContext;

    public TaskRepository()
    {
        _dataContext = new DataContextDataContext();
    }

    public List<Task> GetAllTasks()
    {
        return _dataContext.Tasks.ToList();
    }

    public Task GetForKeyTable(int keyTable)
    {
        return _dataContext.Tasks.Where(t => t.KeyTable == keyTable).
            FirstOrDefault();
    }

    public void AddTask(Task task)
    {
        task.Project = _dataContext.Projects.SingleOrDefault(
            p => p.KeyTable == task.KeyProject);
        _dataContext.Tasks.InsertOnSubmit(task);
        _dataContext.SubmitChanges();

    }

    public void UpdateTask(Task task)
    {
        //exception occurs here
        _dataContext.Tasks.Attach(task, GetForKeyTable(task.KeyTable)); 
        _dataContext.SubmitChanges();
    }

    public void DeleteTask(Task task)
    {
        _dataContext.Tasks.Attach(task, GetForKeyTable(task.KeyTable));
        _dataContext.Tasks.DeleteOnSubmit(task);
        _dataContext.SubmitChanges();
    }

    public bool ContainsTask(Task task)
    {
        return GetForKeyTable(task.KeyTable) != null;
    }
}

:

, , DataContext. .

, , . ,

_dataContext.Tasks.Attach(task, true);

.

IDisposable , using (TaskRepository taskRepository = new TaskRepository). Dispose() TaskRepository Dispose() .

Update(), Detach() Task. :

public class TaskRepository : IRepository, IDisposable
{
    private DataContextDataContext _dataContext;

    public TaskRepository()
    {
        _dataContext = new DataContextDataContext();
        DataLoadOptions dlo = new DataLoadOptions();
        dlo.LoadWith<Task>(t => t.Project);
        dlo.LoadWith<Task>(t => t.Priority);
        _dataContext.LoadOptions = dlo;
    }

    public List<Task> GetAllTasks()
    {
        return _dataContext.Tasks.ToList();
    }

    public Task GetForKeyTable(int keyTable)
    {
        return _dataContext.Tasks.Where(t => t.KeyTable == keyTable).FirstOrDefault();
    }

    public void AddTask(Task task)
    {
        task.Project = _dataContext.Projects.SingleOrDefault(p => p.KeyTable == task.KeyProject);
        _dataContext.Tasks.InsertOnSubmit(task);
        _dataContext.SubmitChanges();

    }

    public void UpdateTask(Task task)
    {
        task.Detach();

        _dataContext.Tasks.Attach(task, true);  //exception occurs here
        _dataContext.Refresh(RefreshMode.KeepCurrentValues, task);
        _dataContext.SubmitChanges();
    }

    public void DeleteTask(Task task)
    {
        _dataContext.Tasks.Attach(task, GetForKeyTable(task.KeyTable));
        _dataContext.Tasks.DeleteOnSubmit(task);
        _dataContext.SubmitChanges();
    }

    public bool ContainsTask(Task task)
    {
        return GetForKeyTable(task.KeyTable) != null;
    }

    #region IDisposable Members

    public void Dispose()
    {
        _dataContext.Dispose();
    }

    #endregion
}

Detach() :

public void Detach()
{
    this._Project = default(EntityRef<Project>);
    this._Priority = default(EntityRef<Priority>);
}

:

Database layout

.

, .

+3

All Articles