2017-05-29 138 views
1

我无法将EF linq示例转换为OrmLite。我已经掌握了大部分查询,但是一些深度连接或子查询正在解决一些问题。使用OrmLite ServiceStack复杂加入/查询

这是我的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); 

正如你所看到的,我使用了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); 

回答

2

OrmLite提供了一个类型1:在正常的SQL 1个API映射所以它通常更容易转化生成的SQL比EF查询它往往不清楚在什么查询正在生成。

默认情况下OrmLite SELECT的源表,在这种情况下,为OrderProduct

var q = _erpDbConnection.From<OrderProduct>() 

这是当你执行查询什么回来了,即:

List<OrderProduct> results = db.Select(q); 

要包括你需要的相关数据在您的源OrderProduct上定义POCO References,然后可以使用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's dynamic result set APIs之一。


另外请注意,你不能做的嵌套查询在OrmLite,如:

.Where<OrderProduct>(x => x.ProductId != null 
    && !x.Order.ContainsFreeMaterial 
    && !x.Order.IsFitSizeOrder 
    && x.Order.OrderType != OrderType.Stock) 

您需要查询的表中的字段(如你在正常的SQL做),你也可以查询多个表在相同条件下:

.Where<OrderProduct,Order>((op,o) => ...);