Search code examples
c#ormautomapperdapper

Class property for a Foreign key


My question is two fold and related to each other

How to define or write a property inside a class which represents a foreign key and how do you populate it using dapper

Tech i am working with :

  • Using dapper as an ORM

  • Database in MySQL

  • Using WPF/C# .netframework 4.7

For Ex : lets say there is are two entities customer and a product, a customer has a Customer table and a product has a Product table

A customer can have zero or many products and a single product should only relate to one person, so this is a one to many relationship from customer to product

NOTE : I know there can be more customers for a single product and that a customer can buy more than one product, THIS is just a simple example where the problem is not the the database design but how to define those fields that are foreign keys, as properties in a class where the ORM being used is dapper and the DATABASE is MySQL

in Customer table there are 2 fields Customer ID and Customer name

in Product table there are 3 field , Product ID and Product Name and C_CustomerID, here C_CustomerID is the foreign key that references the Customer Table's Primary KEY

so you generally make two classes right a customer and a product Class with its properties for Instance Customer table has

    public int CustomerID { get; set; }

    public string CustomerName { get; set; }

and Product table has

    public int ProductID { get; set; }

    public string ProductName { get; set; }

The problem is how to define the foreign key

is it like this

Option 1.

    public int C_CustomerID { get; set; }

Option 2.

    public List<CustomerID> C_CustomerID { get; set; }

Option 3.

    public List<Customer> C_CustomerID { get; set; }

Option 4.

    public List<Customer> Customer { get; set; }

and how do you populate these, do you use stored procedures or do you use functions from dapper or manual C# code


Solution

  • You should model your data after "real life", not after the database. I will skip your requirement that the product should know who bought it, that's not a simplification, but will only make it harder. A Customer can buy multiple products and should have a list of the products bought. Normally it would be done like this:

    public class Customer
    {
        public int CustomerID { get; set; }
        public string CustomerName 
        public List<Product> Products { get; set; }
    }
    
    public class Product
    {
        public int ProductID { get; set; }
        public string ProductName { get; set; }
    }
    
    

    The foreign key relationship is an implementation detail of your database, it does not belong in your data model. You should therefore create a link table CustomerProductLink containing a CustomerId and a ProductId, here you will add a row for every Product bought by any Customer. The link table is also just an implementation detail, you shouldn't model it. When you load a Customer you tailor your SQL to only load the products that are bought by that customer, something like:

    SELECT * FROM Customers AS C 
        INNER JOIN CustomerProductLink AS L ON C.CustomerID = L.CustomerID
        INNER JOIN Products AS P ON P.ProductId = L.ProductID
        WHERE C.CustomerID = @CustomerID;
    

    You load the customer using Dapper multimapping. This way your model describes the data domain as it is, and how the relationship is modelled gets hidden in your data layer.

    After writing this, I found this tutorial describing pretty much the same thing.