简体   繁体   English

实体框架DbContext更新值无需查询和外键

[英]Entity framework DbContext update value without query and by foreign key

I have a method for updating some tables. 我有一个更新一些表的方法。 For update I need get first of TestProcess , but I don't like that. 对于更新,我需要首先获得TestProcess ,但我不喜欢它。 How can I update TestProcess without select(firstOrDefault) operation, used only for the update operation? 如何在没有select(firstOrDefault)操作的情况下更新TestProcess ,仅用于更新操作?

Example of method: 方法示例:

public void UpdateTestProcess(int id, string updateID)
{
    using (TestEntities context = new TestEntities())
                {
                    TestProcess pr = context.TestProcess.FirstOrDefault(x => x.MyID == id);
                    pr.UpdateID = updateID;             

                    context.TestProcess.Attach(pr);
                    context.ObjectStateManager.ChangeObjectState(pr, EntityState.Modified);
                    context.SaveChanges();
               }
}
TestProcess pr = new TestProcess()
{
    MyID == id,
};

context.Set<TestProcess>().Attach(pr);

pr.UpdateID = updateID;

context.SaveChanges();

If you are setting the value to the default value of that type (for example, setting an int to 0 ) it won't be picked up as a change, and you need to manually set the state. 如果要将值设置为该类型的默认值(例如,将int设置为0 ),则不会将其作为更改进行拾取,您需要手动设置状态。

pr.UpdateID = updateID;
context.Entry(pr).Property(p => p.UpdateID).IsModified = true;

You can put such code away in extension methods, so you can do things like this (I'll leave the implementation as an exercise): 你可以把这些代码放在扩展方法中,这样你就可以做这样的事情(我将把实现留作练习):

Foo entity = this.DbContext.GetEntityForUpdate<Foo>(
    item => item.ID, model.ID
    );

this.DbContext.UpdateProperty(entity, item => item.Name, model.Name);

You can do like that (you probably should have all the test process data): 您可以这样做(您可能应该拥有所有测试过程数据):

TestProcess pr = new TestProcess();

pr.Id = id;
pr.UpdateID = updateID;

context.Attach(pr);
context.ObjectStateManager.ChangeObjectState(pr, EntityState.Modified);
context.SaveChanges();

The code: 编码:

TestProcess testprocess = dbcontext.TestProcesses.Attach(new TestProcess { MyID = id });
tp.UpdateID = updateID;
dbcontext.Entry<TestProcess>(testprocess).Property(tp => tp.UpdateID).IsModified = true;
dbcontext.Configuration.ValidateOnSaveEnabled = false;
dbcontext.SaveChanges();

The result TSQL: 结果TSQL:

exec sp_executesql N'UPDATE [dbo].[TestProcesses]
SET [UpdateID] = @0
WHERE ([MyID] = @1)
',N'@0 bigint,@1 bigint',@0=2,@1=1

Note: 注意:

The "IsModified = true" line, is needed because when you create the new TestProcess object (only with the MyID property populated) all the other properties has their default values (0, null, etc). 需要“IsModified = true”行,因为在创建新的TestProcess对象时(仅填充了MyID属性),所有其他属性都具有其默认值(0,null等)。 If you want to update the DB with a "default value", the change will not be detected by entity framework, and then DB will not be updated. 如果要使用“默认值”更新数据库,实体框架将不会检测到更改,然后不会更新数据库。

In example: 例如:

testprocess.UpdateID = null;

will not work without the line "IsModified = true", because the property UpdateID, is already null when you created the empty TestProcess object, you needs to say to EF that this column must be updated, and this is the purpose of this line. 如果没有“IsModified = true”这一行将无法工作,因为属性UpdateID在创建空的TestProcess对象时已经为空,您需要向EF说这个列必须更新,这就是这一行的目的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM