简体   繁体   English

使用实体框架聚合根和性能

[英]Aggregate roots and perfomance with Entity Framework

I'm trying to implement DDD in my project but I have a performance issue, the model is simple: a calendar (aggregate root) and appointments我正在尝试在我的项目中实现 DDD,但我遇到了性能问题,model 很简单:日历(聚合根)和约会

public class Calendar
{
    public int Id { get; private set; }

    public IList<Appointment> Appointments { get; private set; }

    public void AddAppointment(Appointment appointment)
    {
        var anyOverlapping = Appointments.Any(a => a.Date.Hour == a.Date.Hour);

        if (anyOverlapping)
        {
            throw new Exception();
        }

        // More validations according to the calendar

        Appointments.Add(appointment);
    }
}

public class Appointment
{
    public int Id { get; private set; }
    public DateTime Date { get; private set; }
    public int CalendarId { get; private set; }
}

The problem is that with the DDD approach I have to load the entire appointments collection in the manager/service method.问题是使用 DDD 方法时,我必须在 manager/service 方法中加载整个约会集合。

public void AddAppointment(int calendarId, Appointment appointment)
{
    var calendar = _context.Calendars
        .Include(c => c.Appointments) // Here load all the records in memory, can be thousands
        .FirstOrDefault(c => c.Id == calendarId);

    calendar.AddAppointment(appointment);
    _context.SaveChanges();
}

But with the no DDD approach the manager/service method is:但是没有 DDD方法的管理器/服务方法是:

public void AddAppointment(int calendarId, Appointment appointment)
{
    var anyOverlaping = _context.Appointments
    .Where(a => a.CalendarId == calendarId)
    .Any(a => a.Date.Hour == appointment.Date.Hour); // Don't load all the records into memory
    
    if (anyOverlapping)
    {
        throw new Exception();
    }
    
    // More validations according to the calendar that belongs
    
    _context.Appointments.Add(appointment)
    _context.SaveChanges();
}

How can I keep using a DDD design and still be performing?我怎样才能继续使用 DDD 设计并仍然在执行?

If this is about read performance for querying only use cases you should bypass the domain model classes entirely and read the data the best way that suits you.如果这是关于仅查询用例的读取性能,您应该完全绕过域 model 类并以适合您的最佳方式读取数据。 Eg by using separate read model classes that already only fetch the data needed.例如,通过使用已经只获取所需数据的单独读取 model 类。

If this is about write performance I suggest you use lazy loading with the proxy package .如果这是关于写入性能,我建议您使用代理 package 的延迟加载 With that child data of your aggregate will be loaded from the database on demand only.使用该聚合的子数据将仅按需从数据库加载。 The only thing is that you need to make the corresponding fields virtual in your models but other than the domain model will be free of any dependencies still.唯一的事情是您需要在模型中使相应的字段虚拟化,但除了域 model 之外,仍然没有任何依赖关系。 I think that's a trade-off one can accept.我认为这是一个可以接受的权衡。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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