1

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?

Mightymuke
  • 5,094
  • 2
  • 31
  • 42
user20358
  • 14,182
  • 36
  • 114
  • 186
  • Did your source code get compiled? you can not iterate `foreach (var rec in data)`, plus that you must clean the dto variable on each iteration – Jahan Zinedine Dec 02 '12 at 15:56
  • yes, it did.. I have simplified the code here... – user20358 Dec 02 '12 at 15:57
  • sorry :) I did not copy the code correctly. changed it now. while debugging, I enter the loop for the number of times the records are fetched but each time its a null assignment. – user20358 Dec 02 '12 at 15:59

3 Answers3

0

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.

Community
  • 1
  • 1
Jahan Zinedine
  • 14,616
  • 5
  • 46
  • 70
  • Hi Jani, I could not find any documentation for such kind of mapping where there are two or more tables in the query. – user20358 Dec 05 '12 at 11:59
0

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);
Omu
  • 69,856
  • 92
  • 277
  • 407
  • Thanks. It works well when my linq query is working with just one table. But if you look at my linq query above there are two tables returned. That is where the problem is. – user20358 Dec 03 '12 at 12:23
  • The composite DTO has matching properties from both tables. I have changed the field's names in the BankAccount and Person tables to match the CompositeDTO class's properties, regenerated the EDMX and its class. still no effect... – user20358 Dec 03 '12 at 12:29
0

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?

user20358
  • 14,182
  • 36
  • 114
  • 186