Mapping private attributes of domain objects to Dapper dot net

In most of my projects, I use nHibernate + Fluent mapping, and I recently started playing with Dapper to see if I can move read operations to it.

I follow the DDD approach, so my domain objects do not have public networks. For instance:

public class User
{
    private int _id;
    private string _name;
    private IList<Car> _carList;

    protected User(){} // Fluent Mapping

    public User(string id, string name)
    {
        // validation 
        // ...
        _id = id;
        _name = name;
    }

    public int Id{ get {return _id;} }
    public string Name { get {return _name;} }
    public IList<Car> CarList { get {return _carList;}}         
}

public class Car
{
    private int _id;
    private string _brand;

    protected Car(){} // Fluent Mapping

    public Car(string id, string brand)
    {
        // validation 
        // ...
        _id = id;
        _brand= brand;
    }

    public int Id{ get {return _id;} }
    public string Brand { get {return _brand;} }
}

With Free nHibernate, I can show members for matching:

Id(Reveal.Member<User>("_id")).Column("id");
Map(Reveal.Member<User>("_name")).Column("name");

Is there a way to map my domain objects to Dapper? If so, how?

+5
source share
2 answers

- Dapper; : UserRecord CarRecord. db . Dapper , factory, .

:

        var carRecord = DbConnection.Query<CarRecord>("select * from cars where id = @id", new {id = 1});
        var carEntity = CarFactory.Build(carRecord);

.

+8

Dapper , , , /.

, User Aggregate Root

public class User : AggregateRoot
{
    public int Id { get; private set; }
    public string Name { get; private set; }

    ...
}

GetById

public class UserRepository : Repository<User>, IUserRepository
{
    private UserRepository(IDbConnection dbConnection) : base(dbConnection) {}

    ...

    public User GetById(int id)
    {
        const string sql = @"
            SELECT *
            FROM [User]
            WHERE ID = @userId;
        ";

        return base.DbConnection.QuerySingleOrDefault<User>(
            sql: sql,
            param: new { userId = id }
        );
    }
}

sql Id Name, User, . !

, User , , , / :

public class User : AggregateRoot
{
    public int Id { get; private set; }
    public string Name { get; private set; }

    private readonly IList<Car> _cars = new List<Car>();
    public IEnumerable<Car> Cars => _cars;

    public void PurchaseCar(Car car)
    {
        _cars.Add(car);

        AddEvent(new CarPurchasedByUser { ... });
    }

    public void SellCar(Car car)
    {
        _cars.Remove(car);

        AddEvent(new CarSoldByUser { ... });
    }
}

public class Car : Entity
{
    public int Id { get; private set; }
    public string Brand { get; private set; }
}

, , User?

, , PurchaseCar SellCar ( , ) / :

public User GetById(int id)
{
    const string sql = @"
        SELECT *
        FROM [User]
        WHERE ID = @userId;

        SELECT *
        FROM [Car]
        WHERE UserID = @userId;
    ";

    using (var multi = base.DbConnection.QueryMultiple(sql, new { userId = id })
    {
        var user = multi.Read<User>()
            .FirstOrDefault();

        if (user != null)
        {
            var cars = multi.Read<Car>();

            foreach (var car in cars)
            {
                user.PurchaseCar(car);
            }
        }

        return user;
    }
}

, Domain-Driven Design , , . User.

!

, , System.Reflection !

public User GetById(int id)
{
    const string sql = @"
        SELECT *
        FROM [User]
        WHERE ID = @userId;

        SELECT *
        FROM [Car]
        WHERE UserID = @userId;
    ";

    using (var multi = base.DbConnection.QueryMultiple(sql, new { userId = id })
    {
        var user = multi.Read<User>()
            .FirstOrDefault();

        if (user != null)
        {
            var cars = multi.Read<Car>();

            // Load user car list using Reflection
            var privateCarListField = user.GetType()
                .GetField("_cars", BindingFlags.NonPublic | BindingFlags.Instance);

            privateCarListField.SetValue(car, cars);
        }

        return user;
    }
}
0

All Articles