带有引用的 ServiceStack OrmLite 映射不起作用
ServiceStack OrmLite mapping with references not working
我正在试用 OrmLite,看看是否可以在我的项目中替换 Entity Framework。对于简单的查询,速度非常显着。但是我尝试 map/reference [一对多关系并阅读文档 + 检查 github 页面中的测试代码但没有成功。这是我的例子。有什么我忘记或应该做的事情让它像 Entity Framework 一样工作吗?
例子
// EF: returns +15.000 records + mapped > product.StockItems (slow)
dbContext.Products.Include(x => x.StockItems).ToList();
// OrmLite: returns +100.000 records (NO mapping > product.StockItems)
db.Select<Product>(db.From<Product>().Join<StockItem>());
// OrmLite: +15.000 separate requests to sql server (bad workarround + slow)
foreach (var product in db.Select<Product>())
{
// manual mapping
product.StockItems = db.Select<StockItem>(x => x.ProductId == product.Id);
}
Product.cs
public class Product
{
public int Id { get; set; }
public ProductType ProductType { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public int DisplayOrder { get; set; }
public bool LimitedToStores { get; set; }
public string Sku { get; set; }
public decimal Price { get; set; }
public decimal OldPrice { get; set; }
public decimal SpecialPrice { get; set; }
public decimal DiscountPercentage { get; set; }
public DateTime? DateChanged { get; set; }
public DateTime? DateCreated { get; set; }
//...
[Reference]
public virtual IList<StockItem> StockItems { get; set; } = new List<StockItem>();
}
StockItem.cs
public class StockItem
{
public int Id {get; set;}
[References(typeof(Product))]
public int ProductId { get; set; }
public string Size { get; set; }
public int TotalStockQuantity { get; set; }
public string Gtin { get; set; }
public int DisplayOrder { get; set; }
// ...
[Reference]
public virtual Product Product { get; set; }
}
理想情况下,您的 POCOs/DTOs shouldn't use interfaces 并且您不需要使用 virtual
,因为 ORM 只会填充您自己的 POCO(即它不会像其他 Heavy ORM 那样创建您的模型的代理),我也更喜欢将 [AutoIncrement]
用于整数 ID(除非您需要填充特定的 ID)所以我的模型看起来像:
public class Product
{
[AutoIncrement]
public int Id { get; set; }
public ProductType ProductType { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public int DisplayOrder { get; set; }
public bool LimitedToStores { get; set; }
public string Sku { get; set; }
public decimal Price { get; set; }
public decimal OldPrice { get; set; }
public decimal SpecialPrice { get; set; }
public decimal DiscountPercentage { get; set; }
public DateTime? DateChanged { get; set; }
public DateTime? DateCreated { get; set; }
[Reference]
public List<StockItem> StockItems { get; set; }
}
public class StockItem
{
[AutoIncrement]
public int Id { get; set; }
[References(typeof(Product))]
public int ProductId { get; set; }
public string Size { get; set; }
public int TotalStockQuantity { get; set; }
public string Gtin { get; set; }
public int DisplayOrder { get; set; }
}
OrmLite's POCO References 仅填充 1 级深度并且具有循环关系不是一个好主意,因为它们不可序列化,因此我将删除 StockItems 上的反向引用,因为它不会被填充。
您还需要使用 LoadSelect
才能 query and return POCOs with references,因此对于 return 产品及其 StockItem 引用,您可以这样做:
db.LoadSelect<Product>();
您也可以使用 using Merge extension method to merge 2 disconnected record sets 的 2 个查询 手动填充此字段,例如:
var q = db.From<Product>().Join<StockItem>();
var products = db.Select(q.SelectDistinct());
var stockItems = db.Select<StockItem>();
products.Merge(stockItems);
这会将 Products 与其 StockItems 合并,您可以通过 运行:
快速查看
products.PrintDump();
我正在试用 OrmLite,看看是否可以在我的项目中替换 Entity Framework。对于简单的查询,速度非常显着。但是我尝试 map/reference [一对多关系并阅读文档 + 检查 github 页面中的测试代码但没有成功。这是我的例子。有什么我忘记或应该做的事情让它像 Entity Framework 一样工作吗?
例子
// EF: returns +15.000 records + mapped > product.StockItems (slow)
dbContext.Products.Include(x => x.StockItems).ToList();
// OrmLite: returns +100.000 records (NO mapping > product.StockItems)
db.Select<Product>(db.From<Product>().Join<StockItem>());
// OrmLite: +15.000 separate requests to sql server (bad workarround + slow)
foreach (var product in db.Select<Product>())
{
// manual mapping
product.StockItems = db.Select<StockItem>(x => x.ProductId == product.Id);
}
Product.cs
public class Product
{
public int Id { get; set; }
public ProductType ProductType { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public int DisplayOrder { get; set; }
public bool LimitedToStores { get; set; }
public string Sku { get; set; }
public decimal Price { get; set; }
public decimal OldPrice { get; set; }
public decimal SpecialPrice { get; set; }
public decimal DiscountPercentage { get; set; }
public DateTime? DateChanged { get; set; }
public DateTime? DateCreated { get; set; }
//...
[Reference]
public virtual IList<StockItem> StockItems { get; set; } = new List<StockItem>();
}
StockItem.cs
public class StockItem
{
public int Id {get; set;}
[References(typeof(Product))]
public int ProductId { get; set; }
public string Size { get; set; }
public int TotalStockQuantity { get; set; }
public string Gtin { get; set; }
public int DisplayOrder { get; set; }
// ...
[Reference]
public virtual Product Product { get; set; }
}
理想情况下,您的 POCOs/DTOs shouldn't use interfaces 并且您不需要使用 virtual
,因为 ORM 只会填充您自己的 POCO(即它不会像其他 Heavy ORM 那样创建您的模型的代理),我也更喜欢将 [AutoIncrement]
用于整数 ID(除非您需要填充特定的 ID)所以我的模型看起来像:
public class Product
{
[AutoIncrement]
public int Id { get; set; }
public ProductType ProductType { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public int DisplayOrder { get; set; }
public bool LimitedToStores { get; set; }
public string Sku { get; set; }
public decimal Price { get; set; }
public decimal OldPrice { get; set; }
public decimal SpecialPrice { get; set; }
public decimal DiscountPercentage { get; set; }
public DateTime? DateChanged { get; set; }
public DateTime? DateCreated { get; set; }
[Reference]
public List<StockItem> StockItems { get; set; }
}
public class StockItem
{
[AutoIncrement]
public int Id { get; set; }
[References(typeof(Product))]
public int ProductId { get; set; }
public string Size { get; set; }
public int TotalStockQuantity { get; set; }
public string Gtin { get; set; }
public int DisplayOrder { get; set; }
}
OrmLite's POCO References 仅填充 1 级深度并且具有循环关系不是一个好主意,因为它们不可序列化,因此我将删除 StockItems 上的反向引用,因为它不会被填充。
您还需要使用 LoadSelect
才能 query and return POCOs with references,因此对于 return 产品及其 StockItem 引用,您可以这样做:
db.LoadSelect<Product>();
您也可以使用 using Merge extension method to merge 2 disconnected record sets 的 2 个查询 手动填充此字段,例如:
var q = db.From<Product>().Join<StockItem>();
var products = db.Select(q.SelectDistinct());
var stockItems = db.Select<StockItem>();
products.Merge(stockItems);
这会将 Products 与其 StockItems 合并,您可以通过 运行:
快速查看products.PrintDump();