tmsmith / Dapper-Extensions

Dapper Extensions is a small library that complements Dapper by adding basic CRUD operations (Get, Insert, Update, Delete) for your POCOs. For more advanced querying scenarios, Dapper Extensions provides a predicate system. The goal of this library is to keep your POCOs pure by not requiring any attributes or base class inheritance.
1.79k stars 584 forks source link

Reference mapper does not work properly on reads. #296

Closed a-priestley closed 2 years ago

a-priestley commented 2 years ago

Hey there! So, super simplified example of what I'm trying to do here..

Entities:

Public abstract class EntityBase
{
    public Guid Id { get; set; } = Guid.NewGuid();    
}
Public class Parent : EntityBase
{
    public string Name { get; set; } = default!;
    public Child Child { get; set; } = default!;
}

Public class Child : EntityBase
{
    public string Name { get; set; } = default!;
}

with class mappers:

public class ParentMapper: ClassMapper<Parent>
{
    public ParentMapper()
    {
        Table("Parent");

        Map(x => x.Id).Key(KeyType.Unassigned).Column("ID");
        Map(x => x.Name).Column("Name");
        Map(x => x.Child).Ignore();
        ReferenceMap(x => x.Child).Reference<Child>((c, p) => c.Id == p.Child.Id);
    }
}

public class ChildMapper: ClassMapper<Child>
{
    public ChildMapper()
    {
        Table("Child");

        Map(x => x.Id).Key(KeyType.Unassigned).Column("ID");
        Map(x => x.Name).Column("Name");
    }
}

data layer:

public async Task AddAsync<T>(T entity) where T : class
{
    await _dbConnection.InsertAsync<T>(entity, _dbTransaction);
}

^^ This maps correctly

but:

public async Task<IEnumerable<T>> GetAllAsync<T>() where T : class
{
    var result = await _dbConnection.GetListAsync<T>(transaction: _dbTransaction);
    return result;
}

^^ result.Child is null here.

I am aiming to produce a parent item containing a Child with an Id mapped to the table Parent.ChildID

If I do Map(x => x.Child.Id).Column("ChildID"); I get Linq error Sequence contains more than one matching element

Does Parent {} explicitly need ChildId so I can map the property, or is it possible to do without?

Cheers!

valfrid-ly commented 2 years ago

Hi @a-priestley .

What you need was answered here

a-priestley commented 2 years ago

Hi @a-priestley .

What you need was answered here

Ah, thank you. I will check that out!