2017-05-29 81 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) => ...);