简体   繁体   中英

Entity Framework Core - manually assigning id's to linked entities

I've reviewed other related questions on StackOverflow, but I haven't found one that matches my exact question or scenario.

I have an JavaScript front-end where I have two entities that are linked, so in the front-end I have JSON objects that get 'linked' to each other like this:


entity1

name = "something"

entity2Id = 0

entity2

1st record

id = 0

name = "something else"

2nd record

id = 1

name = "something else again"


I then send the JSON to a .NET back end, and the idea is that as I'm manually specifying the primary key for entity2 and setting that as the 'foreign key' reference in my entity1, Entity Framework then somehow needs to generate a valid id for entity2, and maintain a reference to that id in the entity2id property of entity1.

I suspect I may be getting this all horribly wrong and that there's a fairly standard approach to achieving what I'm trying to do. What should I do to achieve the desired result? (I'm using a SQLite database, which probably doesn't make a difference.)

You have a one-to-many relationship there. To make it easier to explain I'll change your Entit1 to Book and Entity2 to Genre . So something like this:

public class Book
{
    public int Id { get; set; }
    public string Name { get; set; }

    public int GenreId { get; set; }
    public Genre Genre { get; set; }
}

public class Genre
{
    public int Id { get; set; }
    public string Name { get; set; }
    public ICollection<Book> Books { get; set; }
}

You can then use the FluentApi to configure the relationship (most importantly the FK key on Books from Genres

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Book>()
        .HasOne(p => p.Genre)
        .WithMany(b => b.Books)
        .HasForeignKey(p => p.GenreId);
}

Now we can achieve your two scenarios:

1 - Create a new Book along with a new Genre

2 - Create a new Book that uses an existing Genre on db

var bookWithNewGenre = new Book
{
    Name = "Book 1",

    // Here we are creating a new Genre, without Id.
    // GenreId here will have the default value of 0, 
    // which EF will use to find out that it has to be created
    Genre = new Genre { Name = "Mistery"}   
};

var bookWithExistingFictionGenre = new Book
{
    Name = "Book 2",

    // Here we are specifying the GenreId = 1 which already exists in the Database
    GenreId = 1,

    // You don't need to set this to null
    // but I like doing it to make EF and my code clear that I'm using an existing Genre
    Genre = null
};

using (var context = new BookContext())
{
    context.Books.Add(bookWithNewGenre);
    context.Books.Add(bookWithExistingFictionGenre);
    await context.SaveChangesAsync();
}

After saving you'll have this in the database:

保存后查询结果

You'll probably have to change your front-end to start sending also the Genre object along. In cases where it's a new one, the Id will be missing. When you serialize it into your c# types, you can figure it out if you have to create new instance or just maybe check if the Id front-end passed exists or not.

Remarks: I did all this using Sqlite and the EF core packages version 2.2.0-preview1-35029 .

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