У меня есть простой проект в MVC, который я должен отображать в табличном формате сводку клиента, указав для каждого клиента:
- Имя
- Самый последний счет-фактура Ссылка
- Сумма последнего счета (£)
- Количество неоплаченных счетов (#)
- Общая сумма всех неоплаченных счетов (£)
Также я должен использовать эти дватаблицы
CREATE TABLE Customers
(
CustomerId INT,
Name NVARCHAR(100),
Address1 NVARCHAR(100),
Address2 NVARCHAR(100),
Postcode NVARCHAR(100),
Telephone NVARCHAR(15),
CONSTRAINT Customers_PK PRIMARY KEY (CustomerId)
)
CREATE TABLE Invoices
(
InvoiceId INT,
CustomerId INT, -- FK
Ref NVARCHAR(10),
InvoiceDate DATETIME,
IsPaid BIT,
Value DECIMAL,
CONSTRAINT Invoices_PK PRIMARY KEY (InvoiceId)
)
У меня есть несколько вопросов
- Соответствуют ли запросы с Entity Framework требованиям и могу ли я сделать их более эффективными
Этосценарий, который мне предоставили, ДЕЛАЕТ ЗНАЧЕНИЕ ПОЛЕ ЗНАЧЕНИЯ (18,0) - Я НЕ ДУМАЮ, что это хорошая практика - использовать десятичное число (18,0), и это сложный тест, и я должен изменить его на десятичное (18, 4))
Я ИЩУ РЕКОМЕНДАЦИИ КАК МОЖНО улучшить структуру проекта или найти потенциальные ошибки, которые я не видел
В проекте библиотеки классов ProjectName.Domain у меня есть папки:
Репозитории - здесь я помещаю свой общий класс репозитория Entity Framework
public class EntityFrameworkRepository<T> : IRepository<T> where T : class, new()
{
public readonly DbContext _entitiesContext;
public readonly IDbSet<T> _dbSet;
public EntityFrameworkRepository(DbContext entitiesContext)
{
if (entitiesContext == null)
{
throw new ArgumentNullException("entitiesContext");
}
_entitiesContext = entitiesContext;
_dbSet = _entitiesContext.Set<T>();
}
public virtual IQueryable<T> AllIncluding(params Expression<Func<T, object>>[] includeProperties)
{
IQueryable<T> query = _entitiesContext.Set<T>();
foreach (var includeProperty in includeProperties)
{
query = query.Include(includeProperty);
}
return query;
}
public virtual IQueryable<T> All
{
get { return GetAll(); }
}
public T GetSingle(int key)
{
return _dbSet.Find(key);
}
public void Add(T entity)
{
DbEntityEntry entry = this._entitiesContext.Entry(entity);
if (entry.State != EntityState.Detached)
{
entry.State = EntityState.Added;
}
else
{
_dbSet.Add(entity);
}
}
public void Delete(T entity)
{
DbEntityEntry entry = _entitiesContext.Entry(entity);
if (entry.State != EntityState.Deleted)
{
entry.State = EntityState.Deleted;
}
else
{
this._dbSet.Attach(entity);
this._dbSet.Remove(entity);
}
}
public void Update(T entity)
{
/* _entitiesContext.Set<T>().Attach(entity);
_entitiesContext.Entry(entity).State = EntityState.Modified;*/
DbEntityEntry dbEntityEntry = _entitiesContext.Entry<T>(entity);
dbEntityEntry.State = EntityState.Modified;
}
public IQueryable<T> GetAll()
{
return _entitiesContext.Set<T>();
}
public virtual void Save()
{
_entitiesContext.SaveChanges();
}
}
Папка Entitites
public class CustomerListEntity
{
public int CustomerID { get; set; }
public string Name { get; set; }
public string RecentInvoiceRef { get; set; }
public decimal? RecentInvoiceAmount { get; set; }
public int UnpaidInvoicesNumber { get; set; }
public decimal? UnpaidInvoicesTotalAmount { get; set; }
}
Папка Servicecs - где я пытаюсь сохранить свою бизнес-логику, и у меня есть два класса - CustomerService и InvoiceService`
public class CustomerService : ICustomerService
{
private readonly IRepository<Customer> _customerRepository;
public CustomerService(IRepository<Customer> customerrepository)
{
this._customerRepository = customerrepository;
}
public PaginatedList<CustomerListEntity> GetCustomers(int pageIndex, int pageSize, out int totalRecords)
{
var customers = _customerRepository.AllIncluding(x => x.Postcode).OrderBy(x => x.CustomerId).Select(x => new
CustomerListEntity {
Name = x.Name,
CustomerID=x.CustomerId,
RecentInvoiceRef = x.Invoices.OrderByDescending(t => t.InvoiceDate).FirstOrDefault() != null ? x.Invoices.OrderByDescending(t => t.InvoiceDate).FirstOrDefault().Ref : string.Empty,
RecentInvoiceAmount = x.Invoices.OrderByDescending(t=>t.InvoiceDate).FirstOrDefault()!=null? x.Invoices.OrderByDescending(t => t.InvoiceDate).FirstOrDefault().Value:null,
UnpaidInvoicesNumber=x.Invoices.Where(t=>t.IsPaid==false).Count(),
UnpaidInvoicesTotalAmount = x.Invoices.Where(t => t.IsPaid == false).Sum(k=>k.Value)
});
totalRecords = customers.Count();
return customers.ToPaginatedList(pageIndex, pageSize);
}
public Customer GetCustomerByID(int id)
{
return _customerRepository.GetSingle(id);
}
}
public class InvoiceService : IInvoiceService
{
private IRepository<Invoice> _invoiceRepository;
public InvoiceService(IRepository<Invoice> invoiceRepository)
{
this._invoiceRepository = invoiceRepository;
}
public int GetPaidInvoicesNumber()
{
return _invoiceRepository.GetAll().Where(x => x.IsPaid == true).Count();
}
public decimal? GetPaidInvoicesTotal()
{
return _invoiceRepository.GetAll().Where(v => v.IsPaid == true).Sum(t => t.Value);
}
}
Мой второй проект - мой MVC PROJECT, где у меня есть контроллер:
public class CustomersController : Controller
{
private readonly ICustomerService _customerService;
private readonly IInvoiceService _invoiceService;
public CustomersController(ICustomerService customerservice, IInvoiceService invoiceservice)
{
this._customerService = customerservice;
this._invoiceService = invoiceservice;
}
public ActionResult Index(int? pn)
{
int pageSize = 2;
int pageNumber = pn!=null?pn.Value:1;
int totalRecords;
CustomersViewModel vm = new CustomersViewModel();
vm.PaidInvoicesNumber = _invoiceService.GetPaidInvoicesNumber();
vm.PaidInvoicesTotal = _invoiceService.GetPaidInvoicesTotal();
vm.CustomersList = _customerService.GetCustomers(pageNumber, (int)pageSize, out totalRecords);
vm.CurrentPage = pageNumber;
vm.TotalRecords = totalRecords;
vm.PageSize = pageSize;
vm.ResolvePagedUrl = new Func<int?, string>(
(x) => Url.Action("Index", "Customers", new { pn = x }));
return View(vm);
}
public ActionResult Details(int id)
{
var customer = _customerService.GetCustomerByID(id);
return View(customer);
}
}