简体   繁体   中英

EF Core defining “complex” relation

I'm having a hard time defining the relations I want using EF Core(1 to many).

EG:

I am an entity of Task and Employee , each task is given by an employee and also is appointed to an employee. I've created the Task class as follow:

public class Task
{
    public int TaskId { get; set; }
    [ForeignKey("RequestedBy")]
    [Required]
    public int RequestedById { get; set; }
    [Required]

    [ForeignKey("TaskedTo")]
    public int TaskedToId { get; set; }
    public virtual Employee RequestedBy { get; set; }
    public virtual Employee TaskedTo { get; set; }
}

I think I've done it correctly, but I have a problem with my Employee class. Usually (When there's only one join) I would simply create virtual collection of Task Property in Employee.. but what am I supposed to do now? Is this enough to set the relation or should I add virtual properties for these two tasks?

And another thing, when I have an owned entity, with 1-Many relation, is it enough to add the property in the owner entity, and do nothing in the owned one? Or do I have to specify the [Owned] Annotation?

The issue is that you have two one-to-many relationships between the same two entities. For the Employee class you would need two collections, one for each relationship. Additionally, you'll need to use the InverseProperty attribute to tell EF which foreign key goes with which collection:

public class Employee
{
    ...

    [InverseProperty(nameof(Task.RequestedBy))]
    public ICollection<Task> RequestedTasks { get; set; }

    [InverseProperty(nameof(Task.TaskedTo))]
    public ICollection<Task> AssignedTasks { get; set; }
}

You don't need virtual . That's to enable lazy-loading. For the lazy-loading functionality, EF creates a dynamic proxy class that inherits from your entity and overrides the getter on the navigation property. The virtual keyword is required in C# to allow a class member to be overridden.

Also, the Owned attribute is for value objects. It's a way of having a related class whose properties are literally mapped onto the same table or if given its own table, inherently tied to the entity that "owns" it, such that you access that data through the entity, not separately. Neither of which applies here.

Finally, you should reconsider the name Task for this class. .NET already has a Task class, and it's used very frequently. If you name your class Task as well, you'll be having to specify namespaces virtually every time you use either one, which is a pain.

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