我正在使用.net核心2 mvc,我试图在Users和Steps之间建立多到多的关系。这种关系是没有关系的,但是当我查询记录时,我得到了user = null。
这是我的密码:
(applicationUser模型):
public class ApplicationUser : IdentityUser
{
public string Name { get; set; }
public List<StepsUsers> StepUser { get; set; }
}(步骤模型):
public class Steps
{
public int Id { get; set; }
[Required]
public string Name { get; set; }
public List<StepsUsers> StepUser { get; set; }
}StepsUsers模型:
public class StepsUsers : IAuditable
{
public int StepId { get; set; }
public Steps Step { get; set; }
public string UserId { get; set; }
public ApplicationUser User { get; set; }
}在DbContext中,我这样做了:
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<StepsUsers>()
.HasKey(s => new { s.StepId, s.UserId });
builder.Entity<StepsUsers>()
.HasOne(su => su.Step)
.WithMany(s => s.StepUser)
.HasForeignKey(su => su.StepId);
builder.Entity<StepsUsers>()
.HasOne(su => su.User)
.WithMany(s => s.StepUser)
.HasForeignKey(su => su.UserId);
}
public DbSet<MyApp.Models.StepsUsers> StepsUsers { get; set; }现在,当我使用特定的StepsUsers查询StepId实例时,除了User字段是null之外,所有de字段都是正确的。
var stepUsers = await _context.StepsUsers.Where(s => s.StepId == id).ToListAsync();我对另外两个表做了相同的代码,它工作得很好,我不知道为什么会这样,有什么建议吗?
发布于 2018-01-09 13:22:29
造成问题的原因是您忘记将您的许多关系声明为虚拟。另一个改进是将它们声明为虚拟ICollection而不是List。毕竟,ApplicationUser.StepUser4意味着什么?
如果根据“实体框架公约”,配置多到多的关系,则不需要提及连接表(StepsUsers)。实体框架将识别多到多,并将为您创建连接表。如果您坚持使用代码优先约定,您甚至不需要使用fluent API来配置多到多。
在您的设计中,每个ApplicationUser都有零个或多个Steps,每个Step都由零或多个ApplicationUsers完成。
class ApplicationUser
{
public int Id {get; set;}
// every ApplicationUser has zero or more Steps:
public virtual ICollection<Step> Steps {get; set;}
public string Name {get; set;}
...
}
class Step
{
public int Id {get; set;}
// every Step is performed by zero or more ApplicationUsers:
public virtual ICollection<ApplicationUser> ApplicationUsers {get; set;}
public string Name {get; set;}
...
}
public MyDbContext : DbContext
{
public DbSet<ApplicationUser ApplictionUsers {get; set;}
public DbSet<Step> Steps {get; set;}
}这是所有实体框架需要知道的,以确认您配置了一个多到多的关系。实体框架将为您创建连接表和连接表的外键。你不需要声明连接表。
,但是如果没有连接表,我应该如何连接呢?
答案是:不做连接。使用集合代替.
如果你想要所有的ApplicationUsers .用他们所有的步骤..。通常,您将使用连接表进行内部连接,并通过一些组来获取应用程序用户。试过方法语法来连接三个表。吗?它们看起来很可怕,很难理解,容易出错,很难维护。
使用实体框架中的集合,查询就会简单得多:
var result = myDbContext.ApplicationUsers
.Where(applicationUser => applicationUser.Name == ...)
.Select(applicationUser => new
{
// select only the properties you plan to use:
Name = applicationUser.Name,
Steps = applicationUser.Steps
.Where(step => step.Name == ...)
.Select(step => new
{
// again fetch only Step properties you plan to use
Name = step.Name,
...
})
.ToList(),
});实体框架将认识到连接表是必需的,并为您执行它们。
如果你想要的步骤..。他们的ApplicationUsers谁..。你会做一些类似的事情:
var result = myDbContext.Steps
.Where(step => ...)
.Select(step => new
{
Name = step.Name,
... // other properties
ApplicationUsers = step.ApplicationUsers
.Where(applicationUser => ...)
.Select(applicationUser => new
{
...
})
.ToList(),
});根据我的经验,每当我想到使用实体框架使用DbSets执行查询时,无论是在多对多、一对多或一对一的关系中,查询几乎总是可以使用集合而不是连接来创建。他们看起来更简单,他们更容易理解,因此更好地维护。
https://stackoverflow.com/questions/48168594
复制相似问题