动态 LINQ - Entity Framework 6 - 动态更新记录 Select
Dynamic LINQ - Entity Framework 6 - Update Records for Dynamic Select
C#菜鸟。下面是我的代码,现在已经尝试了几个小时来更新我的数据库中的某些字段,并尝试了许多不同的实现,但没有成功。
// Select all fields to update
using (var db = new Entities())
{
// dbFields are trusted values
var query = db.tblRecords
.Where("id == " + f.id)
.Select("new(" + string.Join(",", dbFields.Keys) + ")");
foreach (var item in query)
{
foreach (PropertyInfo property in query.ElementType.GetProperties())
{
if (dbFields.ContainsKey(property.Name))
{
// Set the value to view in debugger - should be dynamic cast eventually
var value = Convert.ToInt16(dbFields[property.Name]);
property.SetValue(item, value);
// Something like this throws error 'Object does not match target type'
// property.SetValue(query, item);
}
}
}
db.SaveChanges();
}
上面的代码在 运行 时不会导致对数据库的任何更改。显然这段代码需要一些清理,但我正在努力让基本功能正常工作。我相信我可能需要做的是以某种方式将 'item' 重新应用回 'query' 但是我没有运气让它工作无论我尝试什么实现我总是收到 'Object does not match target type'.
这个半相似的问题重申了这一点,但我不是很清楚,因为我使用的是动态 LINQ 查询,不能直接引用 属性 名称。
当您执行 SELECT NEW ...
时,它只会选择特定字段,不会为您跟踪更新。我认为,如果您将查询更改为这样,它将起作用:
var query = db.tblRecords.Where(x=>x.id == id);
Entity Framework 将为您执行实体更新,而不是自定义结果。您的 tblRecords
拥有许多实体,如果您希望 Entity Framework 提供帮助,这就是您想要操纵的对象。删除您的投影(对 Select
的调用),查询将直接 return 对象(列太多,是的,但我们稍后会介绍)。
动态更新的执行方式与 C# 中任何其他动态赋值的方式相同,因为您使用的是普通对象。 Entity Framework 将跟踪您所做的更改,并在调用 SaveChanges
时生成并执行相应的 SQL 查询。
但是,如果你想优化并首先停止选择和创建内存中的所有值,即使是那些不需要的值,你也可以执行从内存中更新。如果你自己创建了一个正确类型的对象并分配了正确的ID,你就可以使用Attach()方法将它添加到当前上下文中。从那时起,任何更改都将由 Entity Framework 记录,当您调用 SaveChanges
时,所有内容都应发送到数据库:
// Select all fields to update
using (var db = new Entities())
{
// Assuming the entity contained in tblRecords is named "ObjRecord"
// Also assuming that the entity has a key named "id"
var objToUpdate = new ObjRecord { id = f.id };
// Any changes made to the object so far won't be considered by EF
// Attach the object to the context
db.tblRecords.Attach(objToUpdate);
// EF now tracks the object, any new changes will be applied
foreach (PropertyInfo property in typeof(ObjRecord).GetProperties())
{
if (dbFields.ContainsKey(property.Name))
{
// Set the value to view in debugger - should be dynamic cast eventually
var value = Convert.ToInt16(dbFields[property.Name]);
property.SetValue(objToUpdate, value);
}
}
// Will only perform an UPDATE query, no SELECT at all
db.SaveChanges();
}
C#菜鸟。下面是我的代码,现在已经尝试了几个小时来更新我的数据库中的某些字段,并尝试了许多不同的实现,但没有成功。
// Select all fields to update
using (var db = new Entities())
{
// dbFields are trusted values
var query = db.tblRecords
.Where("id == " + f.id)
.Select("new(" + string.Join(",", dbFields.Keys) + ")");
foreach (var item in query)
{
foreach (PropertyInfo property in query.ElementType.GetProperties())
{
if (dbFields.ContainsKey(property.Name))
{
// Set the value to view in debugger - should be dynamic cast eventually
var value = Convert.ToInt16(dbFields[property.Name]);
property.SetValue(item, value);
// Something like this throws error 'Object does not match target type'
// property.SetValue(query, item);
}
}
}
db.SaveChanges();
}
上面的代码在 运行 时不会导致对数据库的任何更改。显然这段代码需要一些清理,但我正在努力让基本功能正常工作。我相信我可能需要做的是以某种方式将 'item' 重新应用回 'query' 但是我没有运气让它工作无论我尝试什么实现我总是收到 'Object does not match target type'.
这个半相似的问题重申了这一点,但我不是很清楚,因为我使用的是动态 LINQ 查询,不能直接引用 属性 名称。
当您执行 SELECT NEW ...
时,它只会选择特定字段,不会为您跟踪更新。我认为,如果您将查询更改为这样,它将起作用:
var query = db.tblRecords.Where(x=>x.id == id);
Entity Framework 将为您执行实体更新,而不是自定义结果。您的 tblRecords
拥有许多实体,如果您希望 Entity Framework 提供帮助,这就是您想要操纵的对象。删除您的投影(对 Select
的调用),查询将直接 return 对象(列太多,是的,但我们稍后会介绍)。
动态更新的执行方式与 C# 中任何其他动态赋值的方式相同,因为您使用的是普通对象。 Entity Framework 将跟踪您所做的更改,并在调用 SaveChanges
时生成并执行相应的 SQL 查询。
但是,如果你想优化并首先停止选择和创建内存中的所有值,即使是那些不需要的值,你也可以执行从内存中更新。如果你自己创建了一个正确类型的对象并分配了正确的ID,你就可以使用Attach()方法将它添加到当前上下文中。从那时起,任何更改都将由 Entity Framework 记录,当您调用 SaveChanges
时,所有内容都应发送到数据库:
// Select all fields to update
using (var db = new Entities())
{
// Assuming the entity contained in tblRecords is named "ObjRecord"
// Also assuming that the entity has a key named "id"
var objToUpdate = new ObjRecord { id = f.id };
// Any changes made to the object so far won't be considered by EF
// Attach the object to the context
db.tblRecords.Attach(objToUpdate);
// EF now tracks the object, any new changes will be applied
foreach (PropertyInfo property in typeof(ObjRecord).GetProperties())
{
if (dbFields.ContainsKey(property.Name))
{
// Set the value to view in debugger - should be dynamic cast eventually
var value = Convert.ToInt16(dbFields[property.Name]);
property.SetValue(objToUpdate, value);
}
}
// Will only perform an UPDATE query, no SELECT at all
db.SaveChanges();
}