npoco

NPoco One-To-Many and Many-To-Many


I'm having difficulty mapping one-to-many and many-to-many SQL relationships to Lists in my pocos. I've tried all manner of Fetch and Query as well as attributes and I'm not getting the pocos mapped properly. Here's a simplified version of the classes and SQL:

Pocos:

[NPoco.TableName("Product")]
[NPoco.PrimaryKey("ProductId")]
public class Product
{
    public int ProductId { get; set; }
    public List<Category> Categories { get; set; }
    public string Name { get; set; }
    public List<ProductVariant> ProductVariants { get; set; }
}

[NPoco.TableName("Category")]
[NPoco.PrimaryKey("CategoryId")]
public class Category : ModifiedDomainObject
{
    public int CategoryId { get; set; }
    public string Name { get; set; }
}

[NPoco.TableName("ProductVariant")]
[NPoco.PrimaryKey("ProductVariantId")]
public class ProductVariant : ModifiedDomainObject
{
    public int ProductVariantId { get; set; }
    public string Name { get; set; }
}

SQL query:

SELECT[Product].[ProductId], 
[Product].[PublicId], 
[Product].[Name], 
[Category].[CategoryId],
[Category].[Name],
[ProductVariant]
[ProductVariantId],
[ProductVariant].[ProductId],
[ProductVariant].[Name],
FROM[Product]
JOIN[ProductCategory] on[ProductCategory].[ProductId] = [ProductCategory].[ProductId]
JOIN[Category] ON[ProductCategory].[CategoryId] = [Category].[CategoryId]
LEFT OUTER JOIN[ProductVariant] ON[Product].[ProductId] = [ProductVariant].[ProductId]
WHERE[Product].[ProductId] = 1 
ORDER BY[Product].[ProductId], 
[Category].[CategoryId], 
[ProductVariant].[ProductVariantId];

So, Product->ProductVariant is a one-to-many, with the ProductVariant table carrying ProductId; and the Product->Category is a many-to-many with a xref table [ProductCategory] carrying ProductId and CategoryId. The closest I've gotten is the ProductVariant list populated with the correct number of objects, but the values are being mapped from the Product data.

I've worked with PetaPoco for a long time and am now attempting to "upgrade" to NPoco V3. Where with PetaPoco I would use Relators to do the mapping; with NPoco the examples online don't work for me.


Solution

  • With NPoco 3 you can only map 1 one-to-many or many-to-many relation.

    The item that must be present for the examples to work is the [NPoco.PrimaryKey("ProductId")] tag in Product class.

    So you do this:

    string sql = "sql with product-categorie relation";
    List<Product> products = db.Fetch<Product>(x => x.Categories, sql);
    

    or

    string sql = "sql with product-productVariant relation";
    List<Product> products = db.Fetch<Product>(x => x.ProductVariants, sql);
    

    This will get you the list of Products with the list of Categories, or with the list of ProductVariants, but not both.

    You can use the first, get the Products list with the Categories and then:

    foreach(Product aProduct in products) 
    {
        string productVariantSQL = "SQL to retrieve productVariant for current product";
        aProduct.ProductVariants = db.Fetch<ProductVariant>(productVariantSQL);
    }