Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC3 DbContext Get New Model's ID After Save?

I have a model Product with a 1:n relationship with model Product_Tag. I also have a model Tag has a 1:n relationship with Product_Tag.

class Product{
  int ID {get;set;}
  public virtual ICollection<Product_Tag> productTag {get;set;}
}

class Tag {
  int ID {get;set;}
  public virtual ICollection<Product_Tag> productTag {get;set;}

}

class Product_Tag {
  int ID {get;set;}
  int ProductID{get;set;}
  int TagID {get;set;}
  public virtual Product product {get;set;}
  public virtual Tag tag {get;set;}
}

When saving a new Product, I want to be able to save any associations to Tags in Product_Tags. Product_Tag requires a PRoductID and a TagID. I have the TagID's available at save time, but the ProductID will come from thew newly-created Product. How to get the newly-created Product's ID immediately after saving the new Product?

Alternatively, is there a way to just save the Product model with its productTags having only TagID's and get DbContext to fill in the ProductID for me?

like image 282
ZuluAlphaCharlie Avatar asked Feb 20 '23 23:02

ZuluAlphaCharlie


1 Answers

When you add a new entity to the database, its ID will be automatically populated by Entity Framework. You can use it.

using (var context = new MyDbContext())
{
    var product = new Product();
    product.Name = "My product";

    context.Products.Add(product);
    context.SubmitChanges();

    var productId = product.ID; // here you can get ID of added product
}

Also, EF can work with 'many-to-many' relationships, and you don't need to create additional class for relationship itself. If you use code first, you can use this mapping:

public class Product
{
    int ID {get;set;}
    public virtual ICollection<Tag> Tags {get;set;}
}

public class Tag
{
    int ID {get;set;}
    public virtual ICollection<Product> Products {get;set;}
}

// In your DbContext class:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Product>().HasMany(x => x.Tags).WithMany(x => x.Products)
        .Map(m =>
        {
            m.ToTable("Product_Tag"); // Relationship table name
            m.MapLeftKey("ProductID"); // Name of column for product IDs
            m.MapRightKey("TagID"); // Name of column for tag IDs
        });
}

Then, you can do something like this:

using (var context = new MyDbContext())
    {
        var product = new Product();
        product.Name = "My product";
        product.Tags.Add(new Tag {Name = "furniture"});
        product.Tags.Add(new Tag {Name = "food"});

        context.Products.Add(product);
        context.SubmitChanges();
    }

In this case EF automatically creates a new product, two tags and two relationships between created product and tags.

like image 57
whyleee Avatar answered Feb 23 '23 12:02

whyleee