以下代码从我的Activities表中获取尚未在Twitter上发布的所有行。然后它循环并发布每个行的Twitter更新。在这个过程中,我想更新数据库,以表明这些行现在已经“喋喋不休”。
但是,当我尝试更新此值时,我收到错误(如下所示)。我认为这是因为我使用的是匿名类型。但是,如果我使用完整类型,则需要从数据库中提取大量不必要的数据。
有没有办法有效地实现这一目标?或者这是EF迫使我在性能上做出妥协的另一种情况吗?
using (MyEntities context = new MyEntities())
{
var activities = from act in context.Activities
where act.ActTwittered == false
select new { act.ActID, act.ActTitle, act.Category,
act.ActDateTime, act.Location, act.ActTwittered };
foreach (var activity in activities)
{
twitter.PostUpdate("...");
activity.ActTwittered = true; // <== Error: ActTwittered is read-only
}
}
答案 0 :(得分:6)
您可以尝试这样的“虚假对象方法”:
using (MyEntities context = new MyEntities())
{
var activities = from act in context.Activities
where act.ActTwittered == false
select new { act.ActID, act.ActTitle, act.Category,
act.ActDateTime, act.Location, act.ActTwittered };
foreach (var activity in activities)
{
twitter.PostUpdate("...");
// Create fake object with necessary primary key
var act = new Activity()
{
ActID = activity.ActID,
ActTwittered = false
};
// Attach to context -> act is in state "Unchanged"
// but change-tracked now
context.Activities.Attach(act);
// Change a property -> act is in state "Modified" now
act.ActTwittered = true;
}
// all act are sent to server with sql-update statements
// only for the ActTwittered column
context.SaveChanges();
}
这是“理论”代码,不确定它是否有用。
修改强>
不再是“理论上的”了。我已经使用EF 4.1的DbContext
测试了它,它的工作原理如上面的示例代码所述。 (因为DbContext
只是ObjectContext
周围的包装API,所以假设它也适用于EF 4.0几乎是安全的。)
答案 1 :(得分:0)
如果您只是选择“行动”,那么它应该有效。不要忘记在编辑后提交。
答案 2 :(得分:0)
为什么要调用select而不是返回整个对象。如果在架构资源中正确定义了实体框架,那么实体框架将只能更新属性,这当然不是匿名类型的情况。
实体框架永远无法确定属性映射到哪个表和哪个字段。