2014-10-30 88 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,修改它的名字並保存它,沒有密碼。