[英]Complex Join/Query with OrmLite ServiceStack
我无法将EF linq样本转换为OrmLite。 我已经完成了大部分查询操作,但是一些深度联接或子查询正在缓解一些问题。
这是我的EF查询:
var q = from orderProduct in orderProducts
join order in _erpContext.Orders.Include(x => x.BillingAddress.Country) on orderProduct.OrderId equals order.Id
join product in _erpContext.Products.Include(x => x.ProductCategories).Include(x => x.ProductManufacturers) on orderProduct.ProductId equals product.Id
where (storeId == 0 || storeId == order.StoreId) &&
(!startDate.HasValue || startDate.Value <= order.DateCreated) &&
(!endDate.HasValue || endDate.Value >= order.DateCreated) &&
(!orderStatusId.HasValue || orderStatusId == (int)order.OrderStatus) &&
(!orderTypeId.HasValue || orderTypeId == (int)order.OrderType) &&
(!paymentStatusId.HasValue || paymentStatusId == (int)order.PaymentStatus) &&
(!shippingStatusId.HasValue || shippingStatusId == (int)order.ShippingStatus) &&
(!order.Deleted) &&
(!product.Deleted) &&
(categoryId == 0 || product.ProductCategories.Count(pc => pc.CategoryId == categoryId) > 0) &&
(manufacturerId == 0 || product.ProductManufacturers.Count(pm => pm.ManufacturerId == manufacturerId) > 0) &&
(billingCountryId == 0 || order.BillingAddress.CountryId == billingCountryId);
如您所见,我正在Joins中使用Include()函数。 那就是我被卡住的部分。
这是我的OrmLite查询:
var q = _erpDbConnection.From<OrderProduct>()
.Join<Order>((x, y) => x.OrderId == y.Id)
.Join<Product>((x, y) => x.ProductId == y.Id)
.Where<OrderProduct>(x => x.ProductId != null && !x.Order.ContainsFreeMaterial && !x.Order.IsFitSizeOrder && x.Order.OrderType != OrderType.Stock)
.And<Order, Product>((o, p) => !o.Deleted && !p.Deleted);
if (storeId > 0)
{
q = q.And<Order>(x => x.StoreId == storeId);
}
if (billingCountryId > 0)
{
q = q.And<Order>(x => x.BillingAddress.CountryId == billingCountryId);
}
if (startDate.HasValue)
{
q = q.And<Order>(x => x.DateCreated <= startDate);
}
if (endDate.HasValue)
{
q = q.And<Order>(x => x.DateCreated >= endDate);
}
if (orderStatusId.HasValue)
{
q = q.And<Order>(x => (int) x.OrderStatus == orderStatusId);
}
if (orderTypeId.HasValue)
{
q = q.And<Order>(x => (int)x.OrderType == orderTypeId);
}
if (paymentStatusId.HasValue)
{
q = q.And<Order>(x => (int)x.PaymentStatus == paymentStatusId);
}
if (shippingStatusId.HasValue)
{
q = q.And<Order>(x => (int)x.ShippingStatus == shippingStatusId);
}
if (categoryId > 0)
{
q = q.And<Product>(x => x.ProductCategories.Any(y => y.CategoryId == categoryId));
}
if (manufacturerId > 0)
{
q = q.And<Product>(product => product.ProductManufacturers.Any(y => y.ManufacturerId == manufacturerId));
}
var filteredOrderProducts = _erpDbConnection.Select<OrderProduct>(q);
OrmLite在普通SQL上提供了类型化的1:1 API映射,因此通常转换生成的SQL比使用EF查询更容易,而在EF查询中,通常不清楚生成的查询是什么。
默认情况下,OrmLite SELECT是源表,在这种情况下为OrderProduct
:
var q = _erpDbConnection.From<OrderProduct>()
执行查询时返回的是什么,即:
List<OrderProduct> results = db.Select(q);
要包含相关数据,您需要在源OrderProduct
上定义POCO引用 ,然后可以使用Load*
API加载(深度为1级),例如:
List<OrderProduct> results = db.LoadSelect(q);
您还可以使用SelectMulti
一次选择多个表,例如:
var results = db.SelectMulti<OrderProduct, Order, Product>(q);
foreach (var tuple in results)
{
OrderProduct orderProduct = tuple.Item1;
Order order = tuple.Item2;
Product product = tuple.Item3;
}
对于任何其他自定义结果,您需要使用要选择的结果指定一个“自定义选择”,例如:
q.Select<OrderProduct,Order,Product>((op,o,p) =>
new {
op, // all fields from OrderProduct table
o.Id,
p.Name,
etc...
});
但是,然后您需要在包含与上述查询匹配的公共属性的自定义架构中访问自定义结果集,例如:
var results = db.Select<OrderProductView>(q);
或者使用OrmLite的动态结果集API之一 。
还要注意,您不能在OrmLite中执行嵌套查询,例如:
.Where<OrderProduct>(x => x.ProductId != null
&& !x.Order.ContainsFreeMaterial
&& !x.Order.IsFitSizeOrder
&& x.Order.OrderType != OrderType.Stock)
您需要查询表上的字段(就像在普通SQL中一样),还可以使用以下条件查询处于相同条件的多个表:
.Where<OrderProduct,Order>((op,o) => ...);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.