引用不起作用的ServiceStack OrmLite映射不起作用 [英] ServiceStack OrmLite mapping with references not working

查看:138
本文介绍了引用不起作用的ServiceStack OrmLite映射不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试OrmLite,以查看是否可以在项目中替换Entity Framework。在简单查询中,速度非常重要。但是我试图映射/引用[1到多关系,并阅读了文档并检查了github页上的测试代码,但没有成功。这是我的例子。有什么我忘记或应该做的事情才能使其像实体框架那样工作?



示例

  // EF:返回+15.000条记录+映射的> product.StockItems(缓慢)
dbContext.Products.Include(x => x.StockItems).ToList();

// OrmLite:返回+100.000条记录(没有映射> product.StockItems)
db.Select< Product>(db.From< Product>()。Join< StockItem>( ));

// OrmLite:对SQL Server的单独请求+15.000(坏的工作环境+缓慢)
foreach(db中的乘积(选择db.Select< Product>()))
{
//手动映射
product.StockItems = db.Select< StockItem>(x => x.ProductId == product.Id);
}

Product.cs

 公共类产品
{
public int Id {get;组; }
public ProductType ProductType {get;组; }
公共字符串Name {get;组; }
公共字符串说明{get;组; }
public int DisplayOrder {get;组; }
public bool LimitedToStores {get;组; }
公用字串Sku {get;组; }
公有十进制价格{组; }
十进制公共价格OldPrice {get;组; }
公用十进制SpecialPrice {get;组; }
公众十进制DiscountPercentage {get;组; }
公共DateTime? DateChanged {get;组; }
公共DateTime? DateCreated {get;组; }
// ...

[参考]
公共虚拟IList< StockItem> StockItems {get;组; } = new List< StockItem>();

}

StockItem.cs

 公共类StockItem 
{
public int ID {get; set;}
[References(typeof(Product))]
public int ProductId {get;组; }
公共字符串Size {get;组; }
public int TotalStockQuantity {get;组; }
公用字串Gtin {取得;组; }
public int DisplayOrder {get;组; }
// ... ...

[参考]
公共虚拟产品Product {get;组; }
}


解决方案

理想地,您的 POCO / DTO不应使用接口,并且您无需使用虚拟因为ORM仅填充您自己的POCO(即不会像其他重型ORM一样创建模型的代理),所以我也更喜欢对整数ID使用 [AutoIncrement] (除非您需要填充特定的ID,否则我的模型将如下所示:

 公共类产品
{
[AutoIncrement]
public int Id {get;组; }
public ProductType ProductType {get;组; }
公共字符串Name {get;组; }
公共字符串说明{get;组; }
public int DisplayOrder {get;组; }
public bool LimitedToStores {get;组; }
公用字串Sku {get;组; }
公有十进制价格{组; }
公用十进制OldPrice {get;组; }
公用十进制SpecialPrice {get;组; }
公众十进制DiscountPercentage {get;组; }
公共DateTime? DateChanged {get;组; }
公共DateTime? DateCreated {get;组; }

[参考]
public List< StockItem> StockItems {get;组; }
}

公共类StockItem
{
[AutoIncrement]
public int Id {get;组; }
[References(typeof(Product))]
public int ProductId {get;组; }
公共字符串Size {get;组; }
public int TotalStockQuantity {get;组; }
公用字串Gtin {取得;组; }
public int DisplayOrder {get;组; }
}



您还需要使用 LoadSelect 为了查询并返回带有引用的POCO ,因此返回带有StockItem引用的Product即可:

  db.LoadSelect< Product>(); 

您也可以通过使用Merge扩展方法来合并2个未连接的记录集,例如:

  var q = db.From< Product>()。Join< StockItem>(); 
var积= db.Select(q.SelectDistinct());
var stockItems = db.Select< StockItem>();

个产品。Merge(stockItems);

哪个产品将与其StockItems合并,您可以通过运行以下命令快速查看:

  products.PrintDump(); 


I'm trying out OrmLite to see if I can replace Entity Framework in my projects. The speed is quite significant on simple queries. But I tried to map/reference a [1 to many- relation and read the documentation + examined the test code from the github page but without success. This is my example. Is there something I've forgot or should do to get it working like Entity Framework?

Example

// 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; }
}

解决方案

Ideally your POCOs/DTOs shouldn't use interfaces and you don't need to use virtual as ORM only populates your own POCOs (i.e. it doesn't create proxies of your models like other Heavy ORMs), I also prefer to use [AutoIncrement] for integer Ids (unless you need to populate specific Ids) so my Models would look like:

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 only populate 1-level deep and it's not a good idea to have cyclical relationships as they're not serializable so I'd remove the back reference on StockItems as it's not going to be populated.

You also need to use LoadSelect in order to query and return POCOs with references, so to return Product with their StockItem references you can just do:

db.LoadSelect<Product>();

You can also populate this manually with 2 queries by using Merge extension method to merge 2 disconnected record sets, e.g:

var q = db.From<Product>().Join<StockItem>();
var products = db.Select(q.SelectDistinct());
var stockItems = db.Select<StockItem>();

products.Merge(stockItems);

Which will merge Products with their StockItems which you can quickly see by running:

products.PrintDump();

这篇关于引用不起作用的ServiceStack OrmLite映射不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆