2017-03-03 1 views
1

J'essaye OrmLite pour voir si je peux remplacer Entity Framework dans mes projets. La vitesse est assez importante sur de simples requêtes. Mais j'ai essayé de mapper/référence une [1 à plusieurs- relation et lu la documentation + examiné le code de test de la page github mais sans succès. Ceci est mon exemple. Y a-t-il quelque chose que j'ai oublié ou que je devrais faire pour le faire fonctionner comme Entity Framework?ServiceStack Mappage OrmLite avec les références ne fonctionnant pas

Exemple

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

Répondre

2

Idéalement, votre POCOs/DTOs shouldn't use interfaces et vous n'avez pas besoin d'utiliser virtual car ORM ne remplit que vos propres POCO (c.-à-d. il ne crée pas de procurations vos modèles d'autres lourds ORM), je préfère aussi utiliser [AutoIncrement] pour Ids entier (sauf si vous devez remplir Ids spécifiques) pour que mes modèles ressemblerait à ceci:

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 seulement remplir Il n'est pas recommandé d'avoir des relations cycliques car elles ne sont pas sérialisables, donc je supprimerais la référence arrière sur StockItems car elle ne sera pas remplie.

Vous devez également utiliser LoadSelect pour query and return POCOs with references, afin de retourner le produit avec leurs références stockItem vous pouvez simplement faire:

db.LoadSelect<Product>(); 

Vous pouvez également remplir manuellement avec 2 requêtes par using Merge extension method to merge 2 disconnected record sets, par exemple :

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

products.Merge(stockItems); 

qui fusionnera les produits avec leurs stockpièces que vous pouvez rapidement voir en exécutant:

products.PrintDump(); 
+2

Thx @mythz. Exactement ce que je cherchais. Fonctionne très bien. Je vais continuer à convertir mes projets et remplacer EF par OrmLite. L'amélioration des performances est significative. – Nesse