简体   繁体   中英

ASP .NET Core MVC Entity Framework - add data into many-to-many relationship

I would like to insert data into TripApplicationUser table - to save that for example that Jake has enrolled for a trip to London. The table is in my SQL Server in Visual Studio. It has 2 columns: TripId and ApplicationUserId. What should I do with my databaseContext object?

public class ApplicationUser : IdentityUser
    {
        [PersonalData]
        [Column(TypeName = "nvarchar(MAX)")]
        public string FirstName { get; set; }
        [PersonalData]
        [Column(TypeName = "nvarchar(MAX)")]
        public string Surname { get; set; }
        [PersonalData]
        [Column(TypeName = "nvarchar(MAX)")]
        public string BirthDate { get; set; }

        public ICollection<TripApplicationUser> TripApplicationUsers { get; set; }
    }

public class Trip
    {
        public int TripId { get; set; }
        public string TripDate { get; set; }
        public int TripDuration { get; set; }
        public int TripLength { get; set; }
        public int TripSeats { get; set; }

        public int TrailId { get; set; }
        public Trail Trail { get; set; }


        public ICollection<TripApplicationUser> TripApplicationUsers { get; set; }
    }

public class TripApplicationUser
    {
        public int TripId { get; set; }
        public Trip Trip { get; set; }
        public string ApplicationUserId { get; set; }
        public ApplicationUser ApplicationUser { get; set; }
    }

After saving ApplicationUser and Trip entities to db via EF, you can use id's of these objects like that

using  (var context = new ExampleContext()){
   var applicationUser = await 
context.ApplicationUser.AddAsync(entityAppUser);
   var trip = await context.Trip.AddAsync(entityTrip);
   var entityTripApplicationUser = new TripApplicationUser
   {
     TripId = trip.Id,
     ApplicationUserId = applicationUser.Id
     .....//set other props
   };
   var tripAppUser = await context.TripApplicationUser.AddAsync(entityTripApplicationUser);
}

1.First way:

Instantiate the relational table and configure the relationship between the other two tables in the relational table.

Demo1 as below:

Product.cs:

using System.Collections.Generic;

namespace MTM2.Models
{
    public partial class Product
    {
        public long ProductID { get; set; }
        public string ProductName { get; set; }

        //navigation property to Supplier
        public virtual ICollection<ProductSupplier> Supplier { get; set; }
    }
}

Supplier.cs:

using System.Collections.Generic;

    namespace MTM2.Models
    {
        public partial class Supplier
        {
    
            public long SupplierID { get; set; }
            public string SupplierName { get; set; }
    
            // navigation property to Product
            public virtual ICollection<ProductSupplier> Product { get; set; }
        }
    }

MTM2Context.cs:

using Microsoft.EntityFrameworkCore;
using MTM2.Models;

namespace MTM2.Data
{
    public class MTM2Context: DbContext
   
    {
        public MTM2Context(DbContextOptions<MTM2Context> options)
               : base(options)
        {
        }

        public DbSet<Product> Product { get; set; }
        public DbSet<Supplier> Supplier { get; set; }

        public DbSet<ProductSupplier> ProductSupplier { get; set; }
        protected override void OnModelCreating(ModelBuilder builder)
        {
            base.OnModelCreating(builder);

            builder.Entity<ProductSupplier>().HasKey(i => new { i.ProductID, i.SupplierID });
        }
    }
}

ProductSupplier.cs

using System.ComponentModel.DataAnnotations;

namespace MTM2.Models
{
    public class ProductSupplier
    {
        [Key]
        public long ProductID { get; set; }
        public Product Product { get; set; }
        [Key]
        public long SupplierID { get; set; }
        public Supplier Supplier { get; set; }
    }
}

HomeController.cs:

public class HomeController : Controller
    {
        private readonly MTM2Context conn;

        public HomeController(MTM2Context context)
        {
            conn = context;
        }

        public IActionResult Index()
        {
            var A1Product = new Product() { ProductName = "A1" };
            var A2Product = new Product() { ProductName = "A2" };
            var supplier1 = new Supplier() { SupplierName = "B1" };
            var supplier2 = new Supplier() { SupplierName = "B2" };
            var pslist = new List<ProductSupplier>()
            {
                new ProductSupplier() { Product = A1Product, Supplier = supplier1 },
                new ProductSupplier() { Product = A1Product, Supplier = supplier2 },

                new ProductSupplier() { Product = A2Product, Supplier = supplier1 },
                new ProductSupplier() { Product = A2Product, Supplier = supplier2 },

            };
            conn.ProductSupplier.AddRange(pslist);

            conn.SaveChanges();
            return View();
        }
    }

Result:

在此处输入图像描述 在此处输入图像描述

在此处输入图像描述

2.Second way:

when data do not exist in tables, add instances to context, add an instance to navigation property and call SaveChanges method from context. That is possible because Entity Framework, at the time of insert, puts primary key value (if Identity, AutoIncrement) in correspondent entity's property inserted.

Demo 2 as below:

Product.cs:

using System.Collections.Generic;

namespace MtM.Models
{
    public partial class Product
    {
        public Product()
        {
            this.Supplier = new HashSet<Supplier>();
        }

        public long ProductID { get; set; }
        public string ProductName { get; set; }

        //navigation property to Supplier
        public virtual ICollection<Supplier> Supplier { get; set; }
    }
}

Supplier.cs:

using System.Collections.Generic;

namespace MtM.Models
{

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

        public long SupplierID { get; set; }
        public string SupplierName { get; set; }

        // navigation property to Product
        public virtual ICollection<Product> Product { get; set; }
    }
}

ProductSupplier.cs:

namespace MtM.Models
{
    public class ProductSupplier
    {

        public long ProductID { get; set; }
        public Product Product { get; set; }

        public long SupplierID { get; set; }
        public Supplier Supplier { get; set; }
    }
}

MtMContext.cs:

using Microsoft.EntityFrameworkCore;
using MtM.Models;

namespace MtM.Data
{
    public class MtMContext : DbContext
    {
        public MtMContext(DbContextOptions<MtMContext> options)
            : base(options)
        {
        }

        public DbSet<Product> Product { get; set; }
        public DbSet<Supplier> Supplier { get; set; }

       
    }
}

HomeController.cs:

namespace MtM.Controllers
{
    public class HomeController : Controller
    {
        private readonly MtMContext conn;

        public HomeController(MtMContext context)
        {
            conn = context;
        }
        public void Many()
        {
            var A1Product=new Product (){ ProductName="A1"};
            var A2Product = new Product() { ProductName = "A2" };
            var supplier1 = new Supplier() { SupplierName="B1"};
            var supplier2 = new Supplier() { SupplierName = "B2" };
            A1Product.Supplier.Add(supplier1);
            A1Product.Supplier.Add(supplier2);
            A2Product.Supplier.Add(supplier1);
            A2Product.Supplier.Add(supplier2);
            conn.Product.Add(A1Product);
            conn.Product.Add(A2Product);
            conn.SaveChanges();

        }

Result:

在此处输入图像描述 在此处输入图像描述

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM