свободное автоматическое сопоставление динамических компонентов

Кто-нибудь знает, как мы можем автоматически отображать динамические компоненты с помощью Fluent Automapping в NHibernate?

Я знаю, что мы можем отображать обычные классы как компоненты, но не мог понять, как отображать словари как динамические компоненты, используя свободное автоматическое сопоставление.

Спасибо


person ilias    schedule 14.05.2010    source источник


Ответы (2)


Мы успешно использовали следующий подход (с FluentNH 1.2.0.712):

public class SomeClass
{
    public int Id { get; set; }
    public IDictionary Properties { get; set; }
}

public class SomeClassMapping : ClassMap<SomeClass>
{
    public SomeClassMapping()
    {
        Id(x => x.Id);

        // Maps the MyEnum members to separate int columns.
        DynamicComponent(x => x.Properties,
                         c =>
                            {
                                foreach (var name in Enum.GetNames(typeof(MyEnum)))
                                    c.Map<int>(name);
                            });
    }
}

Здесь мы сопоставили все члены некоторого Enum с отдельными столбцами, где все они имеют тип int. Прямо сейчас я работаю над сценарием, в котором мы используем разные типы для динамических столбцов, которые вместо этого выглядят так:

// ExtendedProperties contains custom objects with Name and Type members
foreach (var property in ExtendedProperties)
{
    var prop = property;
    part.Map(prop.Name).CustomType(prop.Type);
}

Это также работает очень хорошо.

Я все еще собираюсь выяснить, как использовать References вместо Map для ссылки на другие типы, которые имеют свое собственное сопоставление...

ОБНОВЛЕНИЕ: случай со ссылками, к сожалению, сложнее, см. эта ветка Google Groups. Короче:

// This won't work
foreach (var property in ExtendedProperties)
{
    var prop = property;
    part.Reference(dict => dict[part.Name]);
}

// This works but is not very dynamic
foreach (var property in ExtendedProperties)
{
    var prop = property;
    part.Reference<PropertyType>(dict => dict["MyProperty"]);
}

Это все на данный момент.

person Oliver    schedule 06.07.2011

Я столкнулся с точно такой же проблемой. С помощью nHibernate мы не можем отобразить это, но самостоятельно я каким-то образом смог решить эту проблему. Мое решение состоит в том, чтобы построить лямбда-выражение на лету и присвоить его объекту. Например, скажем, что:

Пусть моя копия части сайта, на которую ссылается Оливер:

DynamicComponent(
    x => x.Properties,
    part =>
    {
        // Works
        part.Map("Size").CustomType(typeof(string));
        // Works
        var keySize = "Size";
        part.Map(keySize).CustomType(typeof(string));
        // Does not work
        part.Map(d => d[keySize]).CustomType(typeof(string));
 
        // Works
        part.References<Picture>(d => d["Picture"]);
        // Does not work
        var key = "Picture";
        part.References<Picture>(d => d[key]);
    });

И у нас есть проблема, заключающаяся в том, что нам нужно жестко закодировать изображение в отображении. Но каким-то образом после некоторых исследований я создал следующее решение:

var someExternalColumnNames = GetFromSomewhereDynamicColumns();

'x' is a DynamicComponent callback in fluent Nhibernate e.g. (DynamicColumns): DynamicComponent(a => a.DynamicColumns, x => (...content of method below...))

foreach(var x in someExternalColumnNames)
{
    if (x.IsReferenceToPerson == true)
    {
        var param = Expression.Parameter(typeof(IDictionary), "paramFirst");
        var key = Expression.Constant(x.Name);
        
        var me = MemberExpression.Call(param, typeof(IDictionary).GetMethod("get_Item"), new[] { key });
        var r = Expression.Lambda<Func<IDictionary, object>>(me, param);
            
        m.References<Person>(r, x.Name);    
    }
    else
    {
        m.Map(x.Name)
    }
}
//

// Some class that we want to reference, just an example of Fluent Nhibernate mapping
    
public class PersonMap : ClassMap<Person>
    {
        public PersonMap()
        {
            Table("Person");
            Id(x => x.PersonId, "PersonId");
            Map(x => x.Name);
        }
    }

    public class Person
    {
        public virtual Guid PersonId { get; set; }

        public virtual string Name { get; set; }

        public Person()
        { }
    }

Может быть, это было бы полезно

person NeuroXiq    schedule 17.07.2021