简体   繁体   中英

EF4 var object mapping to DTO using valueinjecter

I have linQ query like the one below

 var records = (from P in Person
                join B in BankAccount
                on P.ID equals B.PersonID
                select new { P, B}).ToList();

The person table has a lot of fields but I need to only work with ID & Name. Similarly for BankAccount I only need to work with ID, AccountType and AccountBalance

I then pass the records var type as above to another mapper class with a method like so

    public List<CompositeDTO> MapToDto(IEnumerable<object> data)
    {
        foreach (var rec in data) 
        {
         dto.InjectFrom(rec );
         dtoList.Add(dto);
        }
        return dtoList;
    }

Where CompositeDTO is as below

public class CompositeDTO 
{
  public int PersonID {get; set;}
  public String PersonName {get; set;}
  public int AccountID {get; set;}
  public String AccountType{get; set;}
  public int AccountBalance{get; set;}
}

The problem is I am not able to get any values into my object of type CompositeDTO using dto.InjectFrom(rec )

How should this be done? The documentation here only explained how to do it for one field from two different source classes. Have I missed something ? Can this be done?

As I read on this thread AutoMapper vs ValueInjecter :

you can also use ValueInjecter to map from anonymous and dynamic objects

And AFAIK it must be done without declaring any custom mapping, just by a convention, that must be available. checkout the documentation .

the target.InjectFrom(source) will take properties from source and inject them into target matching them by Name and Type

so in your case the source is an anonymous

 {
   public Person P { get; set; }
   public BankAccount B { get; set; } 
 }

and the target CompositeDTO doesn't has properties named P or B that are of type Person and BankAccount so there's no match


an example of something that will work:

 var source = new { PersonID = 7, PersonName = "Jon" }; var target = new CompositeDTO(); target.InjectFrom(source); 

I think AutoMapper does the job better here. I modified the map method using AutoMapper as below and it worked

public List<CompositeDTO> MapToDto(IEnumerable<object> data)
{
     dtoList = data.Select(Mapper.DynamicMap<CompositeDTO>).ToList();

    //foreach (var rec in data) 
    //{
    // dto.InjectFrom(rec );
    // dtoList.Add(dto);
    //}
    return dtoList;
}

All I needed to do was add the alias I used in the linQ query to the CompositeDTO 's property like so P_PersonID and B_AccountType

I think ValueInjecter should work on adding this feature. I really like not having to create a map before I use it like how it is done in AutoMapper currently for non-dynamic types. I am now using two different object mappers in my code. Is that bad?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM