2013-06-06 22 views
6

Bir varlığın 3 özelliği olup olmadığını kontrol etmek istiyorum. CreatedDate, ModifiedDate ve ModifiedBy.Genel bir varlıkta özellikler nasıl ayarlanır?

Şu anda yalnızca bunları, Nesne İçeriğimin SaveChanges() yönteminde olduğunu bildiğim dosyaları kodladım.

public static bool HasMethod(this object objectToCheck, string methodName) 
{ 
    var type = objectToCheck.GetType(); 
    return type.GetMethod(methodName) != null; 
} 

Ama nasıl doğrudan olmayanlar özelliklerini alacağı: Ben bir nesne buna benzer bir kod kullanarak belli bir yöntem olup olmadığını kontrol etmek mümkün olduğunu biliyorum

bool newEntity = (entry.State == EntityState.Added); 

if (type == typeof(Foo)) 
{ 
    var r = entry.Entity as Foo; 
    if (r != null) 
    { 
    if (newEntity) 
     r.CreatedDate = DateTime.Now; 
    r.ModifiedDate = DateTime.Now; 
    r.ModifiedBy = HttpContext.Current.User.Identity.Name; 
    } 
} 

: Mesela

varlık döküm? Ben Sen yönteminin altında kullanabilirsiniz ASP.Net MVC 4.

+0

Yansıma kullanın. 'PropertyInfo'. – Romoku

+0

Belki [dinamik] (http://msdn.microsoft.com/en-us/library/dd264736.aspx) bunun için kullanılabilir, ancak emin değilim. – dowhilefor

+0

Başlıklarda etiket eklemenin bir anlamı yok. Daha fazla bilgi için lütfen http://meta.stackexchange.com/q/19190/147072 adresini okuyun. – Patrick

cevap

12

kullanıyorum

if (HasMethod(entry.Entity)) 
     entry.Entity.ModifiedDate = DateTime.Now; 

:

Nasıl böyle bir şey yapabilirsiniz. Varsa özelliği ayarlayacaktır. Her aramada GetType kullanılması, bazı ek yüklere neden olabilir, optimizasyon gerektirir.

private void TrySetProperty(object obj, string property, object value) { 
     var prop = obj.GetType().GetProperty(property, BindingFlags.Public | BindingFlags.Instance); 
     if(prop != null && prop.CanWrite) 
      prop.SetValue(obj, value, null); 
    } 

Kullanımı

TrySetProperty(entry.Entity, "ModifiedDate", DateTime.Now); 
+0

Çok hoş. Ne kadar iyi performans gösterdiğini görmek için kıyaslayacağım. Her iki şekilde de zekice. – Smith

+1

@Smith: Tür ve mülkün gerçek araması epey zaman alır, ancak bunları örneğin statik bir sözlüğünde önbelleğe almayı başarırsanız, hız açısından verim çok daha fazla gelişir. – Patrick

5

yapabilirsiniz ya Kullanım yansıma - zaten birkaç kişi tarafından söz edilmiştir - ya da bir arayüz oluşturabilir. Otomatik olarak oluşturulan varlıkları kullanıyorsanız, bunlar partial anahtar sözcüğü ile tanımlanır, böylece aynı projede başka bir sınıf dosyası oluşturabilir ve ona aynı ad alanı ve sınıf tanımını verebilir ve bu arabirimi uygulayabilirsiniz. Ardından, yukarıda gönderdiğiniz kodda, nesnenin arayüzünüzü uygulayıp uygulamadığını kontrol edersiniz, eğer öyleyse, yayınlayın, ardından değerleri ayarlayın.

Arabirimin avantajı, yansıma (pahalı bir işlem olabilir) kullanmadığınız ve ayrıca oluşturduğunuz gelecekteki varlıkların yalnızca arabiriminizi uygulayarak otomatik olarak çalışacağıdır.

Kurum özelliklerinin arabiriminizle tam olarak eşleşmediği durumlarda, herhangi bir ad düzensizliğini ele alacak arabirimi açıkça uygulayabilirsiniz.

Örnek: O arabirimini uygulamak Diyelim ki bir arabirim, IContainAuditProperties tanımlanmış diyelim, ve tüm uygulanabilir varlıkları varsa, tüm yeni/değişmiş varlıklar üzerinde döngü vardır bir bloğun içine aşağıdakileri yapabilirsiniz:

var entity = entry.Entity as IContainAuditProperties; 
if(entity != null) 
{ 
    entity.CreatedDate = DateTime.Now; 
    entity.ModifiedDate = DateTime.Now; 
    //etc. 
} 
+0

Meta veri özelliklerim için zaten birçok seçeneğim olduğu için arabirimi uygulamak için kısmi sınıfları kullanmayla ilgili sorun yaşıyorum. Sorum, doğrudan doğruya referans göstermeden nasıl yayınlanacağıdır. – Smith

+0

Cevabımı bir örnek göstermek için güncelledim. –

+1

Brian ile aynı fikirdeyim. Arayüzler kesinlikle buraya gitmenin yolu. –

1

bir nesne bu kodu kullanarak belli bir adla bir kamu ayarlanabilir özelliği vardır olmadığını kontrol edebilirsiniz: o yansıma çok kullandığı olarak

public static bool HasWritableProperty(this object objectToCheck, string propertyName) 
{ 
    var type = objectToCheck.GetType(); 
    //get a property info for the property, but only if it is a public instance property 
    var pi = type.GetProperty(propertyName, BindingFlags.Instance | BindingFlags.Public) 
    //return false if no propery is found 
    if (pi==null) return false; 
    //get the set method for the property 
    var setter = pi.GetSetMethod(); 
    //if it's null the property is not writable 
    return (setter != null); 
} 

Ancak bu çok etkili bir kod değildir.

Bu rotaya giderseniz, bu kodun sonucunu not alacağım, bu nedenle her kontrol en fazla bir kez çalıştırılacaktır.

Projelerimde aslında ne yapıyorum (EF Kod İlkesini kullanıyorum), ortak özelliklere sahip ve BaseEntity sınıfından edinilen somut varlıklara sahip olan BaseEntity sınıfına sahip.Sonra bir FillEntityMetadata yöntemine sahip, yani daha fazla veya bu az: bunun işe yaraması için, ayrıca bir arabirim, IBaseEntity kullanabilir ve aynı şekilde işleyeceğine

protected void FillEntityMetadata(BaseEntity entity, bool isUpdate = false) 
{ 
    // Set audit data. 
    if (!isUpdate) 
    { 
    entity.CreatedBy = CurrentUser.ID; 
    entity.CreatedOn = DateTime.Now; 
    entity.IsActive = true; 
    } 
    entity.LastModifiedBy = CurrentUser.ID; 
    entity.LastModifiedOn = DateTime.Now; 
} 

Not.

İlgili konular