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



我正试图在我的项目中实现DDD,但我遇到了性能问题,模型很简单:日历(聚合根(和约会

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; }
}

问题是,使用DDD方法,我必须将整个约会集合加载到经理/服务方法中。

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();
}

但对于无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();
}

我如何才能继续使用DDD设计并继续执行?

如果这是关于只查询用例的读取性能,您应该完全绕过域模型类,以最适合您的方式读取数据。例如,通过使用已经只获取所需数据的单独读取模型类。

如果这是关于写入性能,我建议您对代理包使用延迟加载。有了该子数据,您的聚合将仅按需从数据库加载。唯一的问题是,您需要在模型中使相应的字段成为虚拟字段,但域模型之外的字段仍然没有任何依赖关系。我认为这是一种可以接受的权衡。

最新更新