我有一个控制器,它将视图模型返回到视图,它工作得很好。我想迁移到存储库模式,但在存储库中获取正确的语法时遇到问题。我已经创建了存储库及其界面。
public interface IShippingRepository
{
IQueryable<ShippingCommHdr> All { get; }
IQueryable<ShippingCommHdr> AllIncluding(params Expression<Func<ShippingCommHdr, object>>[] includeProperties);
void InsertOrUpdate(ShippingCommHdr shippingcommhdr);
void Delete(int id);
void Save();
}
以下是我要移动到存储库的控制器形式的代码:
public ViewResult ShippingSummary()
{
CPLinkEntities context = new CPLinkEntities();
var shipments =
from h in context.ShippingCommHdrs
where (h.CompletedDate == null)
join
e in context.vHr_Employees on h.CreatedBy equals e.ID
join
s in context.Shippers on h.ShipperID equals s.ShipperID
join
r in context.vAaiomsSites on h.ShipToSiteID equals r.SiteID
join
c in context.vHr_Employees on h.CreatedBy equals c.ID
join
p in context.vHr_Employees on h.FromSitePOC equals p.ID
select new
{
h.ID,
ShippedToSite = r.SiteName,
h.DateShipped,
h.EstDeliveryDate,
h.TrackingNo,
h.HeaderComments,
h.ShippingCommLI.Count,
s.Shipper,
CreatedBy = c.LastName,
FromSitePoc = p.LastName
};
var model = new List<ShippingSummaryVM>();
foreach (var h in shipments)
{
var viewModel = new ShippingSummaryVM
{
ID = h.ID,
ShippedToSite = h.ShippedToSite,
DateShipped = h.DateShipped,
EstDeliveryDate = h.EstDeliveryDate,
TrackingNo = h.TrackingNo,
FromSitePOC = h.FromSitePoc,
Shipper = h.Shipper,
HeaderComments = h.HeaderComments,
NumOrders = h.Count,
CreatedBy = h.CreatedBy,
};
model.Add(viewModel);
}
return View(model);
}
如果我能让这个控制器/存储库工作,那么我就可以相当快地迁移所有其他控制器/存储库。 感谢您的任何帮助
我将向存储库接口添加一个方法定义,以便执行查询。存储库可以为此查询指定一个有意义的名称:
public interface IShippingRepository
{
IQueryable<Shipment> GetShipments()
// ...
}
在控制器中,您需要存储库的实例。您可以将其注入构造函数,或在构造函数中创建构造函数,但无论哪种方式,存储库都需要在后台与 CPLinkEntities 上下文进行通信。您需要将上下文传递到存储库中,以便存储库使用。
public class SomeController : Controller
{
IShippingRepository _shippingRepository;
public SomeController()
{
_shippingRepository = new ShippingRepository(new CPLinkEntities());
}
public ViewResult ShippingSummary()
{
var shipments = _shippingRepository.GetShipments();
// ....
}
}
具体的存储库定义可能如下所示。
public class ShippingRepository : IShippingRepository
{
CPLinkEntities _entities;
ShippingRepository (CPLinkEntities entities)
{
_entites = entities;
}
public IQueryable<Shipment> GetShipments()
{
return from ship in _entities.Ships join ... join ... select
}
}
您的控制器方法基本上有 2 个职责
- 运行查询
- 将查询结果映射到视图模型
您可以将该查询放入存储库中,然后可以使用自动映射器工具(如自动映射器或 ValueInjecter)来帮助您将查询结果映射到视图模型。
生成的控制器方法将简单地调用存储库以获取 CPLinkEntities 的列表。 然后,您的控制器方法可以获取这些实体,然后调用自动映射器为您提供 ShippingSummaryVM 的列表。 我留下了一些实现细节,但这应该可以让您对如何实现您所要求的内容有一个高层次的了解。
选项 A:具有更强的域模型。 您的存储库将负责加载根级域对象,您让底层 OR/M 处理对象遍历。 您的控制器将在装运上调用方法以查找尚未完成的装运。 你将返回一个装运对象,并可以遍历到相关实体,以获取站点名称以及 VM 所需的其他详细信息
选项 B:具有为每个实体返回 all 的存储库,然后在业务或服务层中执行联接。 实体框架不会加载所有内容,即使您说 ShippingRepository.All。 它仅在最后一个负责时刻加载(当您需要具体化结果时)。 因此,您可以有一种业务方法,该方法在每个实体上加入"全部",并根据完成日期进行筛选,然后返回结果。
选项 A 更好,但可能需要做更多的工作。