简体   繁体   中英

Entity Framework Core: One-to-Many with no foreign key?

I have a ASP MVC .NET Core (C#) project and because of business reasons, SQL tables cannot have foreign keys, thus, EF models do not map the relations (entity.HasMany....).

Suppose that EF generates a model for the entity Project and one for Task . I want a relation between the two of them. A Project has many Tasks and a Task belongs to one Project . The task has the project Id in the database (but remember, it is not set as a FK).

Now I want through LINQ to Entity obtain a list of projects and while I'm at it, get list of tasks for each one of then. I have achieved this by creating a custom class CustomProject (aside from the one created by EF) and doing this:

List<CustomProject> projects = (from p in db.Project
                                select new CustomProject {
                                   //Properties
                                   Tasks = db.Tasks.Where(t => t.IdProject == p.IdProject).ToList()
                                }).ToList();

The thing is, I don't want to create custom classes nor use that notation, I just want to use db.Projects.Include("Tasks") and that's it.

Now I don't mind creating custom classes but as long as I don't have also almost the same thing but created by EF (having Project and CustomProject , only one of them), I don't know if for this there's a way for telling EF something like "Hey, this custom class, that I've created manually, relates to this table in the database and map it this way...".

PS I've heard that it goes something like creating another partial class but I don't know...

Thanks

I just want to use db.Projects.Include("Tasks") and that's it...

You cannot do that because to use Include() method you'll require a data relationship (ie foreign-key based relationship).

The thing is, I don't want to create custom classes nor use that notation

Without a foreign-key based relationship, I don't think you have much choice with any better notation - you have to use the Select() projection.

You can avoid creating the CustomProject model by adding a collection of Task in your Project model annotated with [NotMapped] , like below -

public class Project
{
    public int Id { get; set; }
    public string Title { get; set; }

    [NotMapped]
    public List<Task> Tasks { get; set; }
}

public class Task
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int ProjectId { get; set; }
}

Without the [NotMapped] attribute EF would create a one-to-many relation based on the navigation property Tasks in Project and the foreign-key property ProjectId in Task . The [NotMapped] will prevent that.

Then you can do your query with the Project model, like -

List<Project> projects1 = (from p in dbCtx.Projects
                            select new Project
                            {
                                Id = p.Id,
                                Name = p.Name,
                                Tasks = dbCtx.Tasks.Where(t => t.ProjectId == p.Id).ToList()
                            }).ToList();

Or, like -

List<Project> projects = dbCtx.Projects
    .Select(p => new Project
    {
        Id = p.Id,
        Name = p.Name,
        Tasks = dbCtx.Tasks.Where(t => t.ProjectId == p.Id).ToList()
    }).ToList();

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