Entity framework Can';无法从链接表中获取数据

Entity framework Can';无法从链接表中获取数据,entity-framework,asp.net-web-api,Entity Framework,Asp.net Web Api,我有这样的限制: public class ApplicationUser : IdentityUser { public Profile UserProfile { get; set; } } public class Profile { public Profile() { ... Events = new List<Event>();

我有这样的限制:

 public class ApplicationUser : IdentityUser
    {
        public Profile UserProfile { get; set; }
    }

public class Profile
    {
        public Profile()
        {
            ...
            Events = new List<Event>();
            ...
        }
        public int Id { get; set; }
        public string Name { get; set; }
        public string ApplicationUserId { get; set; }
        public ApplicationUser ApplicationUser { get; set; }
        public virtual ICollection<Event> Events { get; set; }
}
public class Event
    {
        public int Id { get; set; }
        public int WhereProfileId { get; set; }
        public int WhoProfileId { get; set; }

        [ForeignKey("WhereProfileId")]
        [InverseProperty("Events")]
        public virtual Profile WhereProfile { get; set; }

        [ForeignKey("WhoProfileId")]
        public virtual Profile WhoProfile { get; set; }
        public string Text { get; set; }
        public DateTime Posted { get; set; }
    }
课程:

public class Profile
    {
        public Profile()
        {
            EventsIAmWho = new List<Event>();
            EventsIAmWhere = new List<Event>();
        }
        public int Id { get; set; }
        public string Name { get; set; }
        public string ApplicationUserId { get; set; }
        public ApplicationUser ApplicationUser { get; set; }
        public string AvatarUrl { get; set; }
        public virtual ICollection<Event> EventsIAmWho { get; set; }
        public virtual ICollection<Event> EventsIAmWhere { get; set; }
 }
public class Event
    {
        public int Id { get; set; }
        public int WhereProfileId { get; set; }
        public int WhoProfileId { get; set; }

        [ForeignKey("WhereProfileId")]
        public virtual Profile WhereProfile { get; set; }
        [ForeignKey("WhoProfileId")]
        public virtual Profile WhoProfile { get; set; }
        public string Text { get; set; }
        public DateTime Posted { get; set; }
    }
公共类配置文件
{
公众简介()
{
EventsIAmWho=新列表();
EventsIAmWhere=新列表();
}
公共int Id{get;set;}
公共字符串名称{get;set;}
公共字符串applicationSerID{get;set;}
公共应用程序用户应用程序用户{get;set;}
公共字符串AvatarUrl{get;set;}
公共虚拟ICollection EventsIAmWho{get;set;}
公共虚拟ICollection事件在此处{get;set;}
}
公开课活动
{
公共int Id{get;set;}
public int WhereProfileId{get;set;}
public int WhoProfileId{get;set;}
[ForeignKey(“WhereProfileId”)]
公共虚拟配置文件,其中配置文件{get;set;}
[外键(“WhoProfileId”)]
公共虚拟配置文件WhoProfile{get;set;}
公共字符串文本{get;set;}
发布的公共日期时间{get;set;}
}

事件应该使用哪个配置文件、WhoProfile或WhereProfile来关联回UserProfile

您需要明确设置概要文件和事件之间的关系。EF可以使用约定在简单情况下解决这些问题,但它将使用类型名称而不是属性名称来尝试和解决FK关系

即,如果您刚刚:

public virtual Profile WhoProfile { get; set; } 
如果表中有一个名为ProfileId的字段,它可能会解析。添加第二个配置文件属性,或希望相对于属性名称(WhoProfile)而不是类型(Profile)命名FK时,需要显式

在建模时使用
上的
modelBuilder

// EF6
modelBuilder.Entity<Profile>()
    .HasMany(x => x.Events)
    .WithRequired(x => x.WhoProfile)
    .HasForeignKey(x => x.WhoProfileId);

//EF Core
modelBuilder.Entity<Profile>()
    .HasMany(x => x.Events)
    .WithOne(x => x.WhoProfile)
    .Required()
    .HasForeignKey(x => x.WhoProfileId);
您还可以向上导航关系。例如,如果您想要一个用户配置文件及其特定用户的事件,则不必在该用户处启动查询,但可以从配置文件生成查询:

var profile = _context.Profiles
    .Where(x => x.User.Id == currentUserId)
    .Include(e => e.EventsIAmWho)
    .Single();
Update2:如果要更新用户配置文件以添加事件,那么使用该事件的导航属性很重要。举个例子:

var eventToAdd = new Event()  
{  
    WhereProfileId = model.ToProfileId, 
    Posted = DateTime.Now,  WhoProfileId = userProfile.Id,  
    Text = model.Text  
};  
await _context.Events.AddAsync(eventToAdd);  
await _context.SaveChangesAsync();
如果要将新事件添加到DbContext正在跟踪的配置文件中:

var profile = _context.Profiles
    .Where(x => x.User.Id == currentUserId)
    .Include(e => e.EventsIAmWho)
    .Single();

var toProfile = _context.Profiles
    .Single(x => x.User.Id == model.ToProfileId);

var event = new Event()  
{  
    WhereProfile = toProfile
    Posted = DateTime.Now,  
    Text = model.Text  
};

userProfile.EventsIAmWho.Add(event);
_context.SaveChanges();

我们加载用户配置文件,假设它通过事件的WhoProfile映射到事件,然后立即加载事件。我们还为Where加载“ToProfile”值,无需担心加载该用户的事件。我们创建事件并设置引用而不是FK id,然后将其添加到profile Events集合并保存。请注意,如果“WhereProfile”与“WhoProfile”是同一用户,那么我们的事件配置文件集合amwhere将不会反映添加的事件(如果它同时应用于两个集合)。(如有必要,可以处理该情况)

首先,感谢您的帮助!我想试试这个,但仍然无法获取
配置文件
事件
。如果我放置断点,我会看到
事件
表包含到
配置文件
表的导航属性,但不幸的是
配置文件
不包含到
事件的这个属性
我使用这个更新的查询
\u context.Users.Where(x=>x.Id==currentUserId)。包括(f=>f.UserProfile)。选择(e=>e.UserProfile).包括(e=>e.EventsIAmWho).FirstOrDefault();}
因此您添加了
.HasMany(x=>x.EventsIAmWho).和一个(x=>x.WhoProfile)之间的modelBuilder映射
?我正在更新答案,以包含一个用于选择所需数据的更清晰选项…是的,我这样做了。也许我创建了错误的数据插入方法?现在我这样做:
var eventToAdd=new Event(){WhereProfileId=model.ToProfileId,post=DateTime。现在,WhoProfileId=userProfile.Id,Text=model.Text};wait _context.Events.AddAsync(eventToAdd);wait _context.savechangesync();
这是在实体中公开FK的一个限制。设置FK不会自动加载相关数据。您应该从上下文中检索UserProfile对象,并设置WhereProfile和WhoProfile引用,而不是FK。设置FKs对于快速和脏更新是可以的,在这种情况下,您可以处理DbContext,而不需要我进一步扩展了关于更新引用而不是FKs的答案。
var profile = _context.Profiles
    .Where(x => x.User.Id == currentUserId)
    .Include(e => e.EventsIAmWho)
    .Single();
var eventToAdd = new Event()  
{  
    WhereProfileId = model.ToProfileId, 
    Posted = DateTime.Now,  WhoProfileId = userProfile.Id,  
    Text = model.Text  
};  
await _context.Events.AddAsync(eventToAdd);  
await _context.SaveChangesAsync();
var profile = _context.Profiles
    .Where(x => x.User.Id == currentUserId)
    .Include(e => e.EventsIAmWho)
    .Single();

var toProfile = _context.Profiles
    .Single(x => x.User.Id == model.ToProfileId);

var event = new Event()  
{  
    WhereProfile = toProfile
    Posted = DateTime.Now,  
    Text = model.Text  
};

userProfile.EventsIAmWho.Add(event);
_context.SaveChanges();