2013-09-11 4 views
4

В настоящее время я использую AutoMapper в моем проекте MVC C# и столкнулся с проблемой преобразования из целого числа в строку.Automapper: преобразовать int в строку

У меня есть два класса:

public class Job 
{ 
    public string Prefix { get; set; } 
    public int JobNumber { get; set; } 
    public int Year { get; set } 
    public int JobPriority { get; set; } 

    public virtual EntityPriority EntityPriority { get; set; } 
} 

public class JobViewModel 
{ 
    public string JobNumberFull { get; set; } 
{ 

Использование Automapper Я хотел бы объединить все три свойства в классе работы, чтобы сформировать строку, которая затем будет сопоставлена ​​JobNumberFull в классе JobViewModel .:

Приставка-номер_задания-Year

для начала я сохранил вещи простыми и не сцепляются поля в строку, я просто попытался взять номер_задания (INT) и сопоставить его JobNumberFull (строка) следующим образом:

Mapper.CreateMap<int, string>().ConvertUsing(Convert.ToString); 
Mapper.CreateMap<Job, JobViewModel>() 
    .ForMember(d => d.JobPriorityId, opt => opt.MapFrom(s => s.EntityPriority.EntityPriorityID)) 
    .ForMember(d => d.JobPriorityLevel, opt => opt.MapFrom(s => s.EntityPriority.PriorityLevel)) 
    .ForMember(d => d.JobNumberFull, opt => opt.MapFrom(s => s.JobNumberYear)); 
Mapper.AssertConfigurationIsValid(); 

var jobsList = db.Jobs.Where(j => j.OperationID == operationId).Project().To<JobViewModel>().ToList(); 

Когда я запускаю это я получаю следующую ошибку

Type 'System.String' does not have a default constructor 

Я знаю, что это делать с

Convert.ToString 

, но я не уверен, что с этим делать! Я могу сделать Convert.ToInt32 при переходе от строки к int, и она работает как удовольствие. Нужно ли создавать конвертер пользовательского типа?

Как я могу получить префикс строки-jobnumber-year?

Вся помощь очень ценится.


UPDATE

Благодаря помощи Джереми и сайт AutoMapper мне удалось получить эту работу здесь мое решение, пожалуйста, комментарий, если вы думаете, есть более элегантное решение :

public class Job 
{ 
    public string Prefix { get; set; } 
    public int JobNumber { get; set; } 
    public int Year { get; set; } 
    public int JobPriority { get; set; } 

    public virtual EntityPriority EntityPriority { get; set; } 
} 

public class JobViewModel 
{ 
    public int JobNumber { get; set; } 
    public int Year { get; set; } 
    public string JobNumberFull { get; set; } 
} 

public enum EntityPriority 
{ 
    Normal = 0, 
    High 
} 

public interface IValueResolver 
{ 
    ResolutionResult Resolve(ResolutionResult source); 
} 

public class JobNumberConverter : ValueResolver<Job, string> 
{ 
    protected override string ResolveCore(Job source) 
    { 
     return string.Format("{0}-{1}-{2}", source.Prefix, source.JobNumber, source.Year); 
    } 
} 

public ActionResult Index() 
{ 
    Mapper.CreateMap<Job, JobViewModel>() 
     .ForMember(jvm => jvm.JobNumberFull, opt => opt.ResolveUsing<JobNumberConverter>()); 
    Mapper.AssertConfigurationIsValid(); 

    List<Job> jobs = new List<Job>(); 

    Job j = new Job() 
    { 
     JobNumber = 1, 
     Prefix = "prefix", 
     Year = 2013, 
     EntityPriority = EntityPriority.High, 
     JobPriority = 2 
    }; 

    Job j2 = new Job() 
    { 
     JobNumber = 2, 
     Prefix = "prefix", 
     Year = 2013, 
     EntityPriority = EntityPriority.High, 
     JobPriority = 2 
    }; 

    Job j3 = new Job() 
    { 
     JobNumber = 3, 
     Prefix = "prefix", 
     Year = 2013, 
     EntityPriority = EntityPriority.High, 
     JobPriority = 2 
    }; 

    jobs.Add(j); 
    jobs.Add(j2); 
    jobs.Add(j3); 

    var jobViewModels = jobs.Select(job => Mapper.Map<JobViewModel>(job)); 

    return View(); 

} 
+1

Это намного проще, если вы не пытаетесь упростить так много и просто указали функцию преобразования для Job в JobViewModel. [Пожалуйста, прочитайте о проблеме XY] (http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) и избегайте его для следующего вопроса. :) – Jeremy

+0

Еще одна вещь, которую нужно отметить - проекция фактически создает запрос LINQ для подачи в EF. С помощью Resolvers или ConvertUsing они не используются в запросе LINQ, только MapFrom. Быстрое решение - просто сделать ToString(). В вашем JobNumberFull используйте MapFrom - но используйте конкатенацию строк вместо string.Format (EF не знает string.Format).Это создаст вместо вас пользовательский SQL-запрос! –

ответ

8

Я думаю, вы можете использовать метод ResolveUsing для его соломы.

  Mapper.CreateMap<Job, JobViewModel>() 
       .ForMember(d => d.JobNumberFull, 
         expression => 
         expression.ResolveUsing(j => string.Format("{0}-{1}-{2}", j.Prefix, j.JobNumber, j.Year))); 
+0

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

+0

Спасибо, что помогли мне добиться результата. – oceanexplorer

+0

Что мне нужно. Ясный и простой. Благодарю. – MRFerocius

0

Вам необходимо указать пользовательскую функцию преобразования для преобразования из Job в JobViewModel.

Mapper.CreateMap<Job, JobViewModel>().ConvertUsing(
    job => new JobViewModel { 
    JobNumberFull = string.Format("{0}-{1}-{2}", 
         job.Prefix, job.JobNumber, Job.Year) 
    }); 

Чтобы преобразовать задание в JobViewModel, используйте функцию Map.

var jobViewModel = Mapper.Map<JobViewModel>(job); 

Чтобы преобразовать список рабочих мест в JobViewModels, используйте метод Select расширения.

var jobViewModels = jobs.Select(job => Mapper.Map<JobViewModel>(job)); 
+1

Джереми благодарен за ваш ответ, это работает в том, что я не получаю сообщение об ошибке, но он не заполняет поля, они все равны нулю. Я добавил обратно в мои строки .ForMember для нескольких других полей, которые я сглаживаю, и они также равны нулю после завершения проекции. – oceanexplorer

+0

Вы пытаетесь создать JobViewModel из задания или задания из JobViewModel? – Jeremy

+0

Ой, а какой тип ListJobsViewModel в строке 2 второго блока кода в вашем вопросе? – Jeremy

Смежные вопросы