我可以更新下面函数中给出的员工记录,还是先查询员工集合,然后更新数据?
public int updateEmployee(App3_EMPLOYEE employee)
{
DBContextDataContext db = new DBContextDataContext();
db.App3_EMPLOYEEs.Attach(employee);
db.SubmitChanges();
return employee.PKEY;
}
或者我是否必须执行以下操作?
public int updateEmployee(App3_EMPLOYEE employee)
{
DBContextDataContext db = new DBContextDataContext();
App3_EMPLOYEE emp = db.App3_EMPLOYEEs.Single(e => e.PKEY == employee.PKEY);
db.App3_EMPLOYEEs.Attach(employee,emp);
db.SubmitChanges();
return employee.PKEY;
}
但我不想使用第二种选择。有没有有效的方法来更新数据?
我通过两种方式得到此错误:
尝试附加或添加非新的实体,可能是从另一个DataContext加载的实体。这不受支持。
答案 0 :(得分:9)
我找到了以下解决此问题的方法:
1)获取并更新实体(我将使用这种方式,因为它对我来说没问题)
public int updateEmployee(App3_EMPLOYEE employee)
{
AppEmployeeDataContext db = new AppEmployeeDataContext();
App3_EMPLOYEE emp = db.App3_EMPLOYEEs.Single(e => e.PKEY == employee.PKEY);
emp.FIRSTNAME = employee.FIRSTNAME;//copy property one by one
db.SubmitChanges();
return employee.PKEY;
}
2)禁用ObjectTrackingEnabled,如下所示
// but in this case lazy loading is not supported
public AppEmployeeDataContext() :
base(global::LinqLibrary.Properties.Settings.Default.AppConnect3DBConnectionString, mappingSource)
{
this.ObjectTrackingEnabled = false;
OnCreated();
}
3)分离所有相关对象
partial class App3_EMPLOYEE
{
public void Detach()
{
this._APP3_EMPLOYEE_EXTs = default(EntityRef<APP3_EMPLOYEE_EXT>);
}
}
public int updateEmployee(App3_EMPLOYEE employee)
{
AppEmployeeDataContext db = new AppEmployeeDataContext();
employee.Detach();
db.App3_EMPLOYEEs.Attach(employee,true);
db.SubmitChanges();
return employee.PKEY;
}
4)在列
中使用时间戳 http://www.west-wind.com/weblog/posts/135659.aspx
5)创建用于更新数据的存储过程并通过db context
调用它答案 1 :(得分:3)
如果没有RowVersion列,则无法将修改后的实体附加到DataContext。相反,只要维护数据更改的副本,您就可以将原始实体存储在应用程序中。然后,当需要保存更改时,您可以将原始实体附加到DataContext,更改其值以匹配修改后的实体值并提交更改。
以下是一个例子:
public int updateEmployee(App3_EMPLOYEE employee, App3_EMPLOYEE originalEmployee)
{
DBContextDataContext db = new DBContextDataContext();
db.App3_EMPLOYEEs.Attach(originalEmployee);
// TODO: Copy values from employee to original employee
db.SubmitChanges();
return employee.PKEY;
}
<强>更新强>
数据库中有一个表,其中包含列ID,名称,注释
// fetch an employee which will not be changed in the application
Employee original;
using(var db = new TestDbDataContext())
{
original = db.Employees.First(e => e.ID == 2);
}
// create an instance to work with
var modified = new Employee {ID = original.ID, Name = original.Name, Notes = original.Notes};
// change some info
modified.Notes = string.Format("new notes as of {0}", DateTime.Now.ToShortTimeString());
// update
using(var db = new TestDbDataContext())
{
db.Employees.Attach(original);
original.Notes = modified.Notes;
db.SubmitChanges();
}
答案 2 :(得分:2)
有关于此主题的讨论here at MSDN s 建议您使用IsVersion字段和Attach方法
答案 3 :(得分:2)
您可以使用此重载附加未附加的已修改实体:
db.App3_EMPLOYEEs.Attach(employee, true);//Attach as modfieied
请注意,要使其正常工作,您需要在表格中使用&#34;版本&#34;类型列#34;时间戳&#34;
答案 4 :(得分:1)
这是我的Repository类中的一个函数,我用它来更新实体
protected void Attach(TEntity entity)
{
try
{
_dataContext.GetTable<TEntity>().Attach(entity);
_dataContext.Refresh(RefreshMode.KeepCurrentValues, entity);
}
catch (DuplicateKeyException ex) //Data context knows about this entity so just update values
{
_dataContext.Refresh(RefreshMode.KeepCurrentValues, entity);
}
}
TEntity是您的数据库类,根据您的设置,您可能只想做
_dataContext.Attach(entity);
答案 5 :(得分:0)
使用此extend方法更新属性为列的所有属性:
public static void SaveToOriginal<T>(this T original, T actual)
{
foreach (var prop in typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance)
.Where(info => info.GetCustomAttribute<System.Data.Linq.Mapping.ColumnAttribute>() != null))
{
prop.SetValue(original, prop.GetValue(actual));
}
}
我的意思是,首先从数据库中恢复原始数据,使用该方法将所有列属性从新元素映射到原始元素,最后进行提交。 我希望这会有所帮助。