У меня простые отношения «один ко многим».Родитель:
public class Customer
{
public Customer(string name, string email)
{
Name = name;
Email = email;
}
public Customer(string name, string email, long mobile)
: this(name, email)
{
Mobile = mobile;
}
//for EF
private Customer() { }
public int Id { get; private set; }
public string Name { get; private set; }
public string Email { get; private set; }
public long? Mobile { get; private set; }
public List<Transaction> Transactions { get; private set; }
public void AddTransactions(IEnumerable<Transaction> transactions)
{
if(Transactions == null)
Transactions = new List<Transaction>();
Transactions.AddRange(transactions);
}
}
Дочерний объект:
public class Transaction
{
public Transaction(DateTimeOffset date, decimal amount, Currency currency, Status status)
{
TransactionDate = date;
Amount = amount;
CurrencyCode = currency;
Status = status;
}
//for EF
private Transaction() { }
public int Id { get; private set; }
public DateTimeOffset TransactionDate { get; private set; }
public decimal Amount { get; private set; }
public Currency CurrencyCode { get; private set; }
public Status Status { get; private set; }
public int CustomerId { get; set; }
public Customer Customer { get; private set; }
}
Существует простой метод, который запрашивает одного клиента и вызывает для него SingleOrDefault.После этого он запрашивает транзакции, и когда они загружаются, транзакции Клиента изменяются с нуля на Count = 5 (транзакции, которые я загрузил).Почему?В конфигурации я не указал .UseLazyLoadingProxies ().
var customerQuery = _dbContext.Customers.AsQueryable();
if (!string.IsNullOrEmpty(request.Email))
customerQuery = customerQuery.Where(c => c.Email == request.Email);
if (request.CustomerId.HasValue)
customerQuery = customerQuery.Where(c => c.Id == request.CustomerId.Value);
var customer = await customerQuery.SingleOrDefaultAsync(cancellationToken)
.ConfigureAwait(false);
//here customer has null collection of transactions
if (customer == null)
throw new NotFoundException("Not Found.");
var transactions = await _dbContext.Transactions
.Where(t => t.CustomerId == customer.Id)
.OrderByDescending(t => t.TransactionDate)
.Take(5)
.ToListAsync(cancellationToken);
//here customer has 5 transactions.
customer.AddTransactions(transactions);
//here it has 10, because of method (following the DDD, it is used for providing business invariant)
EF конфигурация:
public class CustomerEntityConfiguration : IEntityTypeConfiguration<Customer>
{
public void Configure(EntityTypeBuilder<Customer> builder)
{
builder.Property(c => c.Id)
.HasMaxLength(10);
builder.Property(c => c.Email)
.HasMaxLength(25)
.IsRequired();
builder.Property(c => c.Mobile)
.HasMaxLength(10);
builder.Property(c => c.Name)
.HasMaxLength(30)
.IsRequired();
//uniqueness constraint
builder.HasIndex(c => c.Email)
.IsUnique();
builder.HasMany(t => t.Transactions)
.WithOne(t => t.Customer)
.HasForeignKey(t => t.CustomerId);
}
////////////////////////////
public class TransactionEntityConfiguration : IEntityTypeConfiguration<Transaction>
{
public void Configure(EntityTypeBuilder<Transaction> builder)
{
builder.Property(t => t.Amount)
.HasColumnType("decimal(10, 2)");
}
}