Robel Haile
Robel Haile

Reputation: 329

Creating new table with foreign key with Entity Framework Core

I have a DbContext which I via the developer command prompt and creating a migrations schema turn in to my database. But if you look at the product object I have a dictionary object named Parts. That property does not get added to the Product table when the database is updated in the command prompt. I don't even know if it is possible what I am trying to do.

I want to add a table in the database named Parts and then add a foreign key to the Product table which connects the Parts dictionary object in the Product table, and the the new Parts table. Is this possible with Entity Framework Core?

public class ShoppingDbContext : IdentityDbContext<User>
{
    public ShoppingDbContext(DbContextOptions options) : base(options)
    {
    }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        base.OnConfiguring(optionsBuilder);
    }

    public DbSet<Product> Products { get; set; }
    public DbSet<Order> Orders { get; set; }
}

public class Product 
{
    public int ProductId { get; set; }
    public string ProductName { get; set; }
    public double Price { get; set; }
    public int CategoryId { get; set; }
    Dictionary<string, Part> Parts { get; set; }
}

Upvotes: 0

Views: 3807

Answers (4)

patrick
patrick

Reputation: 1

I had the same issue, I resolved it by removing the keyword virtual on the navigation properties and with in the ApplicatinDbContext

Upvotes: 0

Nicholas
Nicholas

Reputation: 1980

Basically like what Arthur said, EF Core does not support it yet.

However, another way is to create a composite table should you want to or if it's viable for your use.

Here's a simple example:

            // -------------- Defining BrandsOfCategories Entity --------------- //

        modelBuilder.Entity<BrandCategory>()
            .HasKey(input => new { input.BrandId, input.CatId })
            .HasName("BrandsOfCategories_CompositeKey");

        modelBuilder.Entity<BrandCategory>()
            .Property(input => input.DeletedAt)
            .IsRequired(false);

        // -------------- Defining BrandsOfCategories Entity --------------- //

   public class BrandCategory
{
    public int CatId { get; set; }
    public int BrandId { get; set; }
    public DateTime? DeletedAt { get; set; }
    public Category Category { get; set; }
    public Brands Brand { get; set; }
}

The DeletedAt is optional of course. This handles M-M Relationships.

Upvotes: 0

Arthur Vickers
Arthur Vickers

Reputation: 7523

EF Core can't currently map a dictionary property directly. If you want to create an association between Products and Parts, then define each of them as an entity. You can then create navigation properties between them--a reference from Part to the Product which it belongs, and a collection of Parts on Product. For example:

public class Product 
{
    public int ProductId { get; set; }
    public string ProductName { get; set; }
    public double Price { get; set; }
    public int CategoryId { get; set; }
    public ICollection<Part> Parts { get; set; }
}

public class Part
{
    public int PartId { get; set; }
    public int ProductId { get; set; }
    public Product Product { get; set;}
}

Part also defines a property ProductId that acts as the FK to the Product entity. You don't need to add that property--EF will simulate it for you if you don't want it, but usually it is easier to deal with entities if the FK is mapped to a property.

Upvotes: 1

jl_
jl_

Reputation: 5539

Relationships are tracked through object references instead of foreign key properties. This type of association is called an independent association.

More Details Here:

https://msdn.microsoft.com/en-us/data/jj713564.aspx

Sample code:

public partial class Product
{
    public Product()
    {
        this.Parts = new HashSet<Part>();
    }

    public int ProductId { get; set; }
    public string ProductName { get; set; }
    public double Price { get; set; }
    public int CategoryId { get; set; }

    public virtual ICollection<Part> Parts { get; set; }

}

Upvotes: 0

Related Questions