C# 使用Linq到SQL更新实体-附加非新实体
我正在尝试编写一个程序,使用LINQtoSQL与数据库进行接口(MSSQLServer2008)。添加和删除似乎还可以,但我无法了解更新 实体上有一个version列,它是数据库上的一个timestamp列,用于linqtosql中内置的乐观锁定。我已将实体上所有字段的Update Check属性设置为Never 我有以下SaveTaskCommand,用于插入和更新实体,具体取决于特定任务是否已添加到数据库中C# 使用Linq到SQL更新实体-附加非新实体,c#,linq-to-sql,repository,C#,Linq To Sql,Repository,我正在尝试编写一个程序,使用LINQtoSQL与数据库进行接口(MSSQLServer2008)。添加和删除似乎还可以,但我无法了解更新 实体上有一个version列,它是数据库上的一个timestamp列,用于linqtosql中内置的乐观锁定。我已将实体上所有字段的Update Check属性设置为Never 我有以下SaveTaskCommand,用于插入和更新实体,具体取决于特定任务是否已添加到数据库中 public class SaveTaskCommand : CustomComma
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;
}
}
任何帮助都将不胜感激
更新
我已使我的存储库实现IDisposable并在调用构造函数的任何地方进行更改,使用(TaskRepository TaskRepository=new TaskRepository)。在TaskRepository
的Dispose()
方法中,我在数据上下文中调用了Dispose()
我还将Update()
方法更改为在我的任务对象上调用Detach()
。我的代码现在如下所示:
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
}
公共类任务存储库:IRepository,IDisposable
{
私有DataContextDataContext_dataContext;
公共任务库()
{
_dataContext=新的DataContextDataContext();
DataLoadOptions dlo=新的DataLoadOptions();
dlo.LoadWith(t=>t.Project);
dlo.LoadWith(t=>t.Priority);
_dataContext.LoadOptions=dlo;
}
公共列表GetAllTasks()
{
return_dataContext.Tasks.ToList();
}
公共任务GetForKeyTable(int-keyTable)
{
返回_dataContext.Tasks.Where(t=>t.KeyTable==KeyTable.FirstOrDefault();
}
公共无效添加任务(任务任务)
{
task.Project=\u dataContext.Projects.SingleOrDefault(p=>p.KeyTable==task.KeyProject);
_dataContext.Tasks.InsertOnSubmit(任务);
_dataContext.SubmitChanges();
}
公共无效更新任务(任务)
{
task.Detach();
_dataContext.Tasks.Attach(task,true);//此处发生异常
_刷新(RefreshMode.KeepCurrentValues,任务);
_dataContext.SubmitChanges();
}
公共无效删除任务(任务任务)
{
_task.Attach(task,GetForKeyTable(task.KeyTable));
_dataContext.Tasks.deleteoSubmit(任务);
_dataContext.SubmitChanges();
}
公共bool CONTANSTASK(任务)
{
返回GetForKeyTable(task.KeyTable)!=null;
}
#区域IDisposable成员
公共空间处置()
{
_Dispose();
}
#端区
}
任务上的Detach()方法如下所示:
public void Detach()
{
this._Project = default(EntityRef<Project>);
this._Priority = default(EntityRef<Priority>);
}
public void Detach()
{
此._项目=默认值(EntityRef);
此._Priority=default(EntityRef);
}
作为参考,我的实体如下所示:
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
}
我现在在指定的行中得到以下异常
无法添加密钥已在使用中的实体
在将
任务
对象附加到新对象之前,请尝试从以前的数据上下文中取消附加该对象,或者在整个应用程序中使用数据上下文的单个实例
您可以在这里找到deattach方法的示例:我用新代码更新了原始帖子,并从该链接中找到了建议。我现在有一个不同的例外。你能帮忙吗?好的。。尝试为每个查询使用新的datacontext。。如果附加和取消附加对象,则共享datacontext不是最佳选项。。