我有一个用C#编写的分层应用程序 -
前端 - (获取
Customers
的页面)商家 - (
CustomerService
和Customer
类)DataContracts - (
CustomerDTO
)DataAccess - (
UnitOfWork
和Repositories
)
数据库有一个Customer表超过一百列(很多冗余),所以我使用DTO来填充业务层的Customer对象。在Customer类中,我也从其数据库名称中更改了许多字段的名称,例如ID为CustomerID,FName为名字。
前端使用业务层的服务来获取客户,例如GetAll(), GetByID(int customerID).
我还想提供下面的GetPaged method
。
CustomerService类
public IEnumerable<Customer> GetPaged(
Func<IQueryable<Customer>, IOrderedQueryable<Customer>> orderBy,
int skip,
int take)
{
foreach (var customerDTO in
unitOfWork.CustomerRepository.GetPaged(orderBy, skip, take))
{
yield return new Customer(customerDTO);
}
}
但这不起作用,因为CustomerRepository
基于orderBy
而不是CustomerDTO
期待Customer
。
我不希望前端知道有关CustomerDTO
。
我怎样才能做到这一点?
答案 0 :(得分:0)
您可以使用可用的订单选项公开enum
,然后在GetPaged
中根据收到的枚举值创建OrderBy。
可能的实施可能是:
public enum OrderCustomersBy
{
FirstNameAsc, FirstNameDesc, AgeAsc, AgeDesc
}
在CustomerService中:
private IOrderedQueryable<CustomerDTO> GetOrderBy(OrderCustomersBy orderOption)
{
IOrderedQueryable<CustomerDTO> orderBy = null;
switch (orderOption)
{
case OrderCustomersBy.FirstNameAsc:
// Create order by...
break;
case OrderCustomersBy.FirstNameDesc:
// Create order by...
break;
case OrderCustomersBy.AgeAsc:
// Create order by...
break;
case OrderCustomersBy.AgeDesc:
// Create order by...
break;
default:
throw new NotImplementedException("Order option not implemented: " + orderOption.ToString());
}
return orderBy;
}
public IEnumerable<Customer> GetPaged(Func<IQueryable<Customer>> func, OrderCustomersBy orderOption, int skip, int take)
{
IOrderedQueryable<CustomerDTO> orderBy = this.GetOrderBy(orderOption);
foreach (var customerDTO in unitOfWork.CustomerRepository.GetPaged(orderBy, skip, take))
{
yield return new Customer(customerDTO);
}
}
答案 1 :(得分:0)
我看到两个问题:第一,如何将业务实体映射到DTO,第二,如何在任何列上执行订单?
将业务实体映射到DTO。这可以通过多种方式完成。列举一些:可以使用AutoMapper,您可以使用属性进行简单映射(该属性将包含customDTO或数据库列的属性名称(使用数据库列可能会否定DTO的值))或者您可以从数据库驱动它,数据库的方法有点沉重和元。
我会按照评论中的建议使用动态订单。是的,它确实添加了一层抽象,但它减少了维护。
动态排序
public static IQueryable<T> OrderBy<T>(this IQueryable<T> items, string propertyName, SortDirection direction)
{
var typeOfT = typeof(T);
var parameter = Expression.Parameter(typeOfT, "parameter");
var propertyType = typeOfT.GetProperty(propertyName).PropertyType;
var propertyAccess = Expression.PropertyOrField(parameter, propertyName);
var orderExpression = Expression.Lambda(propertyAccess, parameter);
string orderbyMethod = (direction == SortDirection.Ascending ? "OrderBy" : "OrderByDescending");
var expression = Expression.Call(typeof(Queryable), orderbyMethod, new[] { typeOfT, propertyType }, items.Expression, Expression.Quote(orderExpression));
return items.Provider.CreateQuery<T>(expression);
}
在我更改实体的那天结束时,我对更改应用程序中其他位置的代码不感兴趣。