Ваш класс ApplicationUser
представляет таблицу в базе данных.Он не отражает использование данных в таблице.
Довольно многие считают хорошей практикой отделить структуру базы данных от использования данных.Это разделение довольно часто выполняется с использованием шаблона хранилища.Репозиторий является абстракцией внутренней структуры данных базы данных.Он позволяет добавлять функциональность к вашим классам, не требуя этой функциональности в классах элементов управления, которые взаимодействуют с базой данных.
Существует множество статей о хранилище. Этот помог мне понять, какую функциональность я должен добавить в классы своей сущности, а какие в хранилище.
Так что вам понадобится класс, который представляет элементы в вашей таблице базы данных итот, который представляет applicationUsers
только с их LatestTransaction
Класс, который представляет таблицу базы данных:
class ApplicationUser : IdentityUser
{
public int Id {get; set;}
public string FirstName { get; set; }
public string LastName { get; set; }
public virtual List<TransactionModel> Transactions { get; set; }
}
ApplicationUser с последней транзакцией
class AppicationUserExt : <base class needed?>
{
public int Id {get; set;}
public string FirstName { get; set; }
public string LastName { get; set; }
public TransactionModel LatestTransaction { get; set; }
}
Функция для получения вашего расширенного ApplicationUser - это функция расширения вашего ApplicationUser
.Входные данные: IQueryable<ApplicationUser
Выходные данные: IQueryable<ApplicationUserExt>
static class MyDbContextExtensions
{
// returns ne ApplicationUserExt for every ApplicationUser
public IQueryable<ApplicationUserExt> ToExtendedUsers(this IQueryable<ApplicationUser> applicationUsers)
{
return applicationUsers
.Select(user => new ApplicationUserExt()
{
Id = user.Id,
FirstName = user.FirstName,
LastName = user.LastName,
LatestTransaction = user.Trnasactions
.OrderByDescenting(transaction => transaction.CreationDate)
.FirstOrDefault(),
}
}
}
}
Поэтому, когда у вас есть запрос с нужными вам ApplicationUsers, вы можете использовать ToExtendedUsers()
, чтобы получить расширенные suers
using (var dbContext = new MyDbContext(...))
{
// you wanted to have a query like:
var result dbContext.ApplicationUsers
.Where(user => user.FirstName = "John"
&& user.LastName = "Doe");
// you'll have to add ToExtendedUsers:
var result = dbContext.ApplicationUsers
.Where(user => user.FirstName = "John"
&& user.LastName = "Doe");
.ToExtendedUsers();
}
Поскольку результат по-прежнему является IQueryable, запрос еще не выполнен.Вы все еще можете добавить операторы LINQ до того, как запрос будет выполнен:
var result2 = result
.Where(user.LatestTransaction.Year == 2018)
.GroupBy(user => user.LatestTransaction.Date)
.OrderBy(group => group.Key)
.Take(10)
.ToList();
Вы видите, что вы все еще можете выполнять все виды LINQ, если это ApplicationUser
.Как только вам понадобится LatestTransaction
, вы преобразуете его в ApplicationUserExt
и продолжаете объединять свои операторы linq.