带有引用的 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 sets2 个查询 手动填充此字段,例如:

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();