2010-04-13 9 views
5

एक आवेदन के लिए एक संस्करण में व्यापक डेटाबेस फिल्टर के लिए अपनी खोज में, मैं निम्नलिखित कोड लिखा है के लिए एक AutoMappingOverride प्रदान करने के लिए सबसे अच्छा तरीका है इंटरफेस पर काम न करें, मैं इसे लागू करने का एक तरीका ढूंढ रहा हूं। वर्तमान में मैं कि इंटरफ़ेस को लागू करता है प्रत्येक वर्ग के लिए यह (बल्कि बोझिल) जिस तरह से उपयोग कर रहा हूँ:क्या fluentnhibernate automapper में एक अंतरफलक

public class SomeVersionedEntity : IModelId, IVersionAware 
{ 
    public virtual int Id { get; set; } 
    public virtual string Version { get; set; } 
} 

public class SomeVersionedEntityOverride : IAutoMappingOverride<SomeVersionedEntity> 
{ 
    #region IAutoMappingOverride<SomeVersionedEntity> Members 

    public void Override(AutoMapping<SomeVersionedEntity> mapping) 
    { 
     mapping.ApplyFilter<VersionFilter>(); 
    } 

    #endregion 
} 

मैं IClassmap इंटरफेस आदि को देख कर दिया है, लेकिन वे ApplyFilter विधि पहुंचने का एक तरीका प्रदान करने के लिए नहीं है , इसलिए मुझे यहां कोई सुराग नहीं मिला है ...

चूंकि मैं शायद इस समस्या में पहला व्यक्ति नहीं हूं, मुझे पूरा यकीन है कि यह संभव होना चाहिए; मैं तो बस काफी यकीन है कि नहीं यह कैसे काम करता हूँ ..

संपादित करें:

का उपयोग करना:

इस तरह से मैं इसे हल करने की कोशिश की है: मैं एक सामान्य समाधान के लिए थोड़ा और करीब मिल गया है

public abstract class AutomappingInterfaceAlteration<I> : IAutoMappingAlteration 
{ 
    public void Alter(AutoPersistenceModel model) 
    { 
     model.OverrideAll(map => 
     { 
      var recordType = map.GetType().GetGenericArguments().Single(); 
      if (typeof(I).IsAssignableFrom(recordType)) 
      { 
       this.GetType().GetMethod("overrideStuff").MakeGenericMethod(recordType).Invoke(this, new object[] { model }); 
      } 
     }); 
    } 

    public void overrideStuff<T>(AutoPersistenceModel pm) where T : I 
    { 
     pm.Override<T>(a => Override(a)); 
    } 

    public abstract void Override<T>(AutoMapping<T> am) where T:I; 
} 

और एक विशिष्ट कार्यान्वयन:

01,235,164 एक सामान्य वर्ग एक अंतरफलक को लागू करने वर्गों के लिए परिवर्तन लागू करने के लिए
public class VersionAwareAlteration : AutomappingInterfaceAlteration<IVersionAware> 
{ 
    public override void Override<T>(AutoMapping<T> am) 
    { 
     am.Map(x => x.Version).Column("VersionTest"); 
     am.ApplyFilter<VersionFilter>(); 
    } 
} 

दुर्भाग्य से मैं अब निम्न त्रुटि मिलती है:

[InvalidOperationException: Collection was modified; enumeration operation may not execute.] 
    System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource) +51 
    System.Collections.Generic.Enumerator.MoveNextRare() +7661017 
    System.Collections.Generic.Enumerator.MoveNext() +61 
    System.Linq.WhereListIterator`1.MoveNext() +156 
    FluentNHibernate.Utils.CollectionExtensions.Each(IEnumerable`1 enumerable, Action`1 each) +239 
    FluentNHibernate.Automapping.AutoMapper.ApplyOverrides(Type classType, IList`1 mappedProperties, ClassMappingBase mapping) +345 
    FluentNHibernate.Automapping.AutoMapper.MergeMap(Type classType, ClassMappingBase mapping, IList`1 mappedProperties) +43 
    FluentNHibernate.Automapping.AutoMapper.Map(Type classType, List`1 types) +566 
    FluentNHibernate.Automapping.AutoPersistenceModel.AddMapping(Type type) +85 
    FluentNHibernate.Automapping.AutoPersistenceModel.CompileMappings() +746 

संपादित करें 2: मैं थोड़ा आगे पाने में कामयाब रहे; मैं अब "अवहेलना" आह्वान प्रत्येक वर्ग है कि इंटरफ़ेस को लागू करता है के लिए प्रतिबिंब का उपयोग:

public abstract class PersistenceOverride<I> 
{ 

    public void DoOverrides(AutoPersistenceModel model,IEnumerable<Type> Mytypes) 
    { 
     foreach(var t in Mytypes.Where(x=>typeof(I).IsAssignableFrom(x))) 
      ManualOverride(t,model); 
    } 

    private void ManualOverride(Type recordType,AutoPersistenceModel model) 
    { 
     var t_amt = typeof(AutoMapping<>).MakeGenericType(recordType); 
     var t_act = typeof(Action<>).MakeGenericType(t_amt); 
     var m = typeof(PersistenceOverride<I>) 
       .GetMethod("MyOverride") 
       .MakeGenericMethod(recordType) 
       .Invoke(this, null); 
     model.GetType().GetMethod("Override").MakeGenericMethod(recordType).Invoke(model, new object[] { m }); 
    } 

    public abstract Action<AutoMapping<T>> MyOverride<T>() where T:I; 
} 

public class VersionAwareOverride : PersistenceOverride<IVersionAware> 
{ 
    public override Action<AutoMapping<T>> MyOverride<T>() 
    { 
     return am => 
     { 
      am.Map(x => x.Version).Column(VersionFilter.COLUMNNAME); 
      am.ApplyFilter<VersionFilter>(); 
     }; 
    } 
} 
हालांकि

, एक या अन्य कारणों मेरी उत्पन्न HBM फ़ाइलों को किसी "फिल्टर" फ़ील्ड शामिल नहीं है .... हो सकता है कि किसी के लिए अब मुझे थोड़ा और मदद कर सकता है ??

उत्तर

1

जाहिर है, धाराप्रवाह-निबर्ननेट के वर्तमान संस्करण में एक बग था। जब आप Automapper.Override < टी > का उपयोग करते हैं तो फ़िल्टर कॉपी नहीं किए जाते थे।

मैंने स्रोत को फोर्क किया, बग तय किया, परीक्षण किया, और अब मैंने गिटूब पर फ्लेंटेंब लड़कों को पुल अनुरोध भेजा है।

अभी के लिए, आप http://github.com/ToJans/fluent-nhibernate/commit/29058de9b2bc3af85bc433aa6f71549f7b5d8e04

पर तय sourcecode डाउनलोड कर सकते हैं वहाँ अब भी कैसे यह करने के लिए पर एक पूरा ब्लॉग पोस्ट है: http://www.corebvba.be/blog/post/How-to-override-interface-mappings-and-creata-a-generic-entity-version-filter-in-fluent-nhibernate.aspx