Как найти исходное свойство по имени плоского свойства с помощью ValueInjecter

Это аналог того же вопроса (но с AutoMapper). Я использую ValueInjecter и меня интересует, есть ли решение.

Упрощенный пример кода:

// get a list of viewModels for the grid.
// NOTE: sort parameter is flattened property of the model (e.g. "CustomerInvoiceAmount" -> "Customer.Invoice.Amount"
// QUESTION: how do I get original property path so I can pass it to my repository for use with Dynamic LINQ?
public HttpResponseMessage Get(string sort)
{
    var models = _repo.GetAll(sort) // get a list of domain models
    var dto = _mapper.MapToDto(models); // get a list of view models that are flattened  via dto.InjectFrom<FlatLoopValueInjection>(models);

    var response = new HttpResponseMessage();
    response.CreateContent(vehicles);

    return response;
}

person zam6ak    schedule 07.06.2012    source источник
comment
посмотрите на исходный код для инъекций flatloop и unflatloop, может быть то, что вам нужно   -  person Omu    schedule 07.06.2012
comment
также было бы полезно (для меня, чтобы понять, что вам нужно), если бы вы показали свои входные данные и какой результат вы хотите получить от этих входных данных (постарайтесь сделать ваши вопросы понятными, например, вопросы о соревнованиях по программированию, например projecteuler.net/problem=12)   -  person Omu    schedule 08.06.2012
comment
@Chuck Norris Я думал, что ссылка на тот же вопрос AutoMapper объяснит цель, но я дал разъяснение в ответе ниже.   -  person zam6ak    schedule 08.06.2012
comment
в идеале вы должны были бы спросить: у меня есть FooBarName и объект obj.Foo.Bar.Name, как мне получить строку Foo.Bar.Name   -  person Omu    schedule 08.06.2012
comment
@Chuck Norris Хотя я согласен, что пример мог бы быть более конкретным, я думаю, что вопрос довольно ясен ... FooBarName - это сглаженное свойство, а Foo.Bar.Name - исходное свойство. Также я просто взял название вопроса для AutoMapper и немного изменил его. Так что, если не ясно, это не моя вина :) j/k   -  person zam6ak    schedule 08.06.2012
comment
всегда так, все думают, что их вопрос очень ясен, но это не так, из заголовка я понимаю только то, что вы хотите получить конечное имя свойства, а в вашем вопросе у вас есть много ненужных вещей, таких как httpresponse, сетка и т. д. и вы ссылаетесь на большой вопрос, который я никогда не прочитаю, он просто слишком большой   -  person Omu    schedule 09.06.2012


Ответы (2)


Что ж, мне удалось кое-что придумать, но мне очень хотелось бы услышать мнение сообщества (и, возможно, @Chuck Norris, написавшего ValueInjecter)...

Итак, чтобы переформулировать проблему....

  • У вас есть плоская модель представления, которая используется в вашем представлении.
  • Представление имеет сетку, столбцы которой являются свойствами указанной модели представления.
  • Когда пользователь нажимает на столбец, sort=columnName передается контроллеру.
  • Итак, теперь вам нужно декодировать сплющенное имя свойства в исходный граф объектов, чтобы передать его в ваш репозиторий для сортировки на стороне сервера (например, с использованием Dynamic Expression APi, Dynamic LINQ или подобных)...

Итак, если Company имеет свойство с именем President типа Employee, а Employee имеет свойство с именем HomeAddress типа Address, а Address имеет строковое свойство с именем Line1, тогда:

"President.HomeAddress.Line1" будет сведено к свойству "PresidentHomeAddressLine1" в вашей модели представления.

Для пользовательской сортировки на стороне сервера Dynamic Linq требуется точечный путь к свойству, а не плоский. Мне нужно, чтобы ValueInjecter распаковывал только плоское свойство! а не весь класс.

Вот что я придумал (соответствующая логика, извлеченная из метода, который делает другие вещи:

// type is type of your unflattened domain model.
// flatProperty is property name in your flattened view model
public string GetSortExpressionFor(Type type, string flatPropertyPath)
{
    if (type == null || String.IsNullOrWhiteSpace(flatPropertyPath))
    {
        return String.Empty;
    }

    // use ValueInjecter to find unflattened property
    var trails = TrailFinder.GetTrails(flatPropertyPath, type.GetInfos(), typesMatch => true).FirstOrDefault();
    var unflatPropertyPath = (trails != null && trails.Any()) ? String.Join(".", trails) : String.Empty;

    return unflatPropertyPath;
}



// sample usage     
var unflatPropertyPath = GetSortExpressionFor(typeof(Company), "PresidentHomeAddressLine1");
// unflatPropertyPath == "President.HomeAddress.Line1"
person zam6ak    schedule 08.06.2012

другой способ сделать это - использовать TrailFinder

IEnumerable<IList<string>> GetTrails(string upn, IEnumerable<PropertyInfo> all, Func<Type, bool> f)

он используется UberFlatter следующим образом:

var trails = TrailFinder.GetTrails(flatPropertyName, target.GetType().GetInfos(), f);

f Func проверяет тип конечного свойства на соответствие определенному условию (возможно, в вашем случае вы могли бы просто вернуть true)

person Omu    schedule 08.06.2012