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();