2015-08-04 18 views
6

Bir öğenin Entity Framework 6.0'ı kullanarak kısmi bir güncelleştirmeyi (temel olarak bir HTTP PATCH) nasıl sorunsuz yapılacağını bulmaya çalışıyorum, ancak buradaki örneklerin sayısıyla karşılaşıyorum. Bu benim için işe yaramaz gibi görünmüyor (EF'nin başka bir sürümü için açık olmayanlar bile).Bir öğenin kısmen güncellenmesi EF6

Ben başarmak istiyorum Ne:

  • varlık önce onu yüklemek zorunda kalmadan güncellenir; yani ben güncellenir dokunma
  • Yalnızca özellikler veritabanına tek girelim -

olduğu gibi başkalarının bırakılır Ben düzgünce çok benzer bir soruya this answer tarafından açıklanan ve gösterilmektedir kazanılmış ettik yakın aşağıdaki kodu ile: Şimdi

public async Task UpdateMyEntity(int id, int? updatedProperty, string otherProperty) 
{ 
    using (var context = new MyDbContext()) 
    { 
     var entity = new MyEntity { Id = id }; 
     context.MyEntities.Attach(entity); 

     if (updatedProperty != null) { entity.Property = updatedProperty.Value; } 
     if (!string.IsNullOrEmpty(otherProperty) { entity.OtherProperty = otherProperty; } 

     await context.SaveChangesAsync(); 
    } 
} 

, bu basit varlıklar için çalışır, ama ben ekli varlık bulunmayan bu nedenle güncellenmeyen gerekli özellikleri ve ilişkilerin çift ve var çünkü varlık doğrulama hataları alıyorsanız değilim . Belirtildiği gibi, bunları görmezden gelmek isterim.

ben debug ve true için context.Entry(entity).Property(e => e.Property).IsModified değişiklikler, bu hat çalıştırıldığında doğruladıktan ve hala dokunmak benzer kontroller için false asla geri tüm özellikleri olduğunu, bu yüzden EF bu işlemek mümkün olacaktır düşündüm.

Yukarıdaki iki kısıtlama altında bunu çözmek mümkün mü? Nasıl?


Güncelleme: Yapmam gerekeni biraz anlıyorum, ama tam olarak çalışmıyor LSU.Net 'ın answer ile

. Mantıksal başvuru özellikleri için başarısız olur. Bir MyEntity güncellemeyi deneyin eğer aşağıdakileri yapın, Şimdi

public class MyEntity 
{ 
    public int Id { get; set; } 
    public int Property { get; set; } 
    [Required] 
    public string OtherProperty { get; set; } 
    [Required] 
    public OtherEntity Related { get; set; } 
} 

public class OtherEntity 
{ 
    public int Id { get; set; } 
    public string SomeProperty { get; set; } 
} 

:,

benim özel doğrulama yönteminde
var entity = new MyEntity { Id = 123 }; // an entity with this id exists in db 
context.MyEntities.Attach(entity); 

if (updatedProperty != null) { entity.Property = updatedProperty.Value; } 

await context.SaveChangesAsync(); 

, the answer below gibi geçersiz

aşağıdaki etki modeli düşünün Değiştirilmemiş olduğundan, OtherProperty gerekli özellikteki doğrulama hatası doğru şekilde kaldırılmıştır. Ancak, Related özelliğinde bir doğrulama hatası alıyorum, çünkü entityEntry.Member("Related") is DbReferenceEntry, DbPropertyEntry değil ve bu nedenle doğrulama hatası yanlış bir hata olarak işaretlenmiyor.

Referans özelliklerini işlemek için ayrı, benzer bir deyim eklemeyi denedim, ancak entityEntry, değiştirilenleri işaretlemiyor gibi görünüyor; relation = member as DbReferenceEntry, relation ile ilişkinin değiştiğini belirtecek hiçbir şey yoktur.

Bu durumda yanlış hatalardan nasıl korunabilirim? Özel olarak ele almam gereken başka durumlar var mı (örneğin bire çok ilişkiler)?

cevap

2

Entity Framework validation with partial updates

@Shimmy değiştirilmemiş özellikleri için doğrulama mantığını ihmal için buraya bazı kodlar yazmıştır. Bu senin için işe yarayabilir.

protected override DbEntityValidationResult ValidateEntity(
    DbEntityEntry entityEntry, 
    IDictionary<object, object> items) 
{ 
    var result = base.ValidateEntity(entityEntry, items); 
    var falseErrors = result.ValidationErrors 
    .Where(error => 
    { 
     var member = entityEntry.Member(error.PropertyName); 
     var property = member as DbPropertyEntry; 
     if (property != null) 
     return !property.IsModified; 
     else 
     return false;//not false err; 
    }); 

    foreach (var error in falseErrors.ToArray()) 
    result.ValidationErrors.Remove(error); 
    return result; 
} 
+0

Bu harika, ancak yine de dokunulmamış başvuru özellikleri için doğrulama hatalarını kaldırmada başarısız oluyor. Bir kullanım durumunu göstermek için OP'yi güncelleyeceğim. –

+0

Lütfen benim güncellememe bakın :) Daha fazla fikir en çok açığız! –