2014-10-30 69 views
0

我有一个名为Client的类,Id,NamePassword必需。如何忽略更新实体框架上的所需列6

我试图更新客户端的名称而不更改密码(我不想在更新之前查询Client以获取密码并将其重新设置)。

我有这样的代码Client.Update()方法中:

db.Entry<Client>(this).State = EntityState.Modified; 
db.Entry(this).Property(q => q.Password).IsModified = false; 
db.SaveChanges(); //gives exception and complains that password was not set 

我可以使它工作SaveChanges之前使用此代码,但我想知道有另一种方式。

db.Configuration.ValidateOnSaveEnabled = false; 

我正在使用asp.net mvc 5.2.2与实体框架6.1.1。

+0

您是否尝试过将每个属性设置为Modified?我不认为你可以说该对象被修改,然后指定只有一个属性不是。 – 2014-10-30 21:24:28

+0

@ErikPhilips即使当我将对象附加到上下文时,我也没有设置与密码相同的异常。 – 2014-11-05 21:11:52

回答

2

看来,在您发送Client对象到UI之前,您首先会删除密码。这是明智的,现在它不能被嗅出。

但是,当您想要保存客户端时,EF的验证点会找到一个空的必需属性,并且存在您的catch-22。通过禁用验证来“解决”这个问题是可能的,但可能有害,因为您可能会错过其他验证。

从数据库重新获取客户端并仅修改其名称是安全地完成此操作的一种方式,但如果您不希望进行额外的数据库往返,则可以应用表分割

您可以将客户端表分成两个类,这些:

public class Client 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public SensitiveClientData SensitiveClientData { get; set; } 
} 

public class SensitiveClientData 
{ 
    public int Id { get; set; } 
    public string Password { get; set; } 
} 

现在你必须告诉EF,两个类映射到一个表。这是如何做到这一点(在DbContext来源的情况下):

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 
    base.OnModelCreating(modelBuilder); 

    modelBuilder.Entity<Client>() 
        .HasRequired(e => e.SensitiveClientData) 
        .WithRequiredPrincipal(); 

    modelBuilder.Entity<Client>().ToTable("Client"); 
    modelBuilder.Entity<SensitiveClientData>().ToTable("Client"); 
} 

这使得创建客户端稍微复杂一些:

var client = db.Clients.Create(); 
client.Name = "Donald Duck"; 
client.SensitiveClientData = new SensitiveClientData { Password = "goofy1" }; 

db.Clients.Add(client); 

db.SaveChanges(); 

但现在你可以不用Include() -ing获取客户端其SensitiveClientData,修改它的名字并保存它,没有密码。