I have a table with tasks and a table with tags between them a many-to-many relationship.

public class DbTask { [Key] public int TaskId { get; set; } public string Name { get; set; } public virtual ICollection<DbTag> Tags { get; set; } } public class DbTag { [Key] public int TagId { get; set; } public String Name { get; set; } public virtual ICollection<DbTask> Tasks{get; set;} } 

I create an object of the DbTask class on the client and add a list of DbTag objects already existing in the database. After that I send the created object to the server, where I add it to the database. When adding via the Add method to the table, not only a record about a new DbTask, but also a new DbTag is entered. How can I make a new entry contact the already existing DbTag?

    1 answer 1

    There are several options for solving this problem:

    1. Create DbTask, select the necessary tags and then add the existing DbTag to the Tags collection.

    2. (more correct, without select) Create a DbTask, add the created DbTag to it and in the context mark each DbTag entity as not modified,

      context.Entry(DbTag).State = EntityState.Unchanged

    allowing the entity framework to create the necessary connections.

    Link to documentation about joining detached entity context

    In general, a good practice in DDD is to bring many-to-many links to one-to-many unidirectional ones. How can it be done in your case and for what? For example, each task can have several tags and when you request a task with its tags, the tag collection will be quite short, but a tag can have a huge number of tasks and it can be a costly operation to request a tag with its tasks in one request. will request tasks using a limit. And there is no possibility to limit entities in Include() in the entity framework. From this it follows that the declaration of the Tasks collection in DbTag can obviously lead to serious consequences and it is better to limit such actions (do not declare the possibility of such a request in the code, that is, remove the Tasks collection from the DbTag code). It will be possible to request all tags marked with a tag through the collection of tags.

    • and if a little to finish the above classes, then ef will make an intermediate table for many-to-many communication, of the form public class DbTagDbTasks { public int DbTagId {get;set;} public int DbTaskId {get;set;}} - Bald
    • I completely forgot, if you leave the Entity Framework to make an intermediate table, but if you delete the Tasks property from DbTag, you will need to set up a mapping in the context - Eugene
    • not for the sake of holivar: and the second method is more correct , I would get the necessary label / task object, add a label / task to the collection and make SaveChanges() and ef add the necessary connections - Bald
    • In the second way to spend less time. Only one insert is needed, and in the first you first need to make a select and only then insert. - Eugene
    • "And there is no possibility to limit entities in Include () in the entity framework." But you can also refuse Eager loading and simply load the necessary objects by request. - Pavel Mayorov