Entity Framework 核心:基于导航 属性 的集合
Entity Framework Core: navigation property based collection
假设我们在 EF Core 中有以下具有以下导航属性的多对多关系场景:
public class Request{
public HashSet<User> Users { get; set; }
}
public class User{
public HashSet<Request> Requests { get; set; }
}
一个用户可能被简单地分配给多个请求,一个请求可能有多个用户。
现在,我想扩展功能,以便每个用户都能够标记他分配给的请求:
public class User{
public HashSet<Request> Requests { get; set; }
public Dictionary<long, bool> RequestsFlags { get; set; } //Request ID (long) and Flag (bool)
}
这样我就可以检查为哪个请求设置了标志并相应地更新 UI。问题是,这两个集合当然必须始终相互同步。
有没有办法确保自定义集合始终与导航保持一致属性?
如果不需要将标记请求的行为持久化到 UserRequest table,那么您可以考虑向名为“Flagged”的请求实体添加一个未映射的 属性。
即
public class Request
{
// normal mapped properties.
[NotMapped]
public bool Flagged { get; set; }
}
这里的限制是它只与已经加载的实体相关。您不能在 EF Linq 查询中使用它。如果用户和请求被投影到视图模型,那么这个 属性 最好在视图模型中提供。
如果您确实需要将标记状态保存到 UserRequest 记录,那么您需要将加入实体引入关系中:
public class User
{
// User properties...
// public virtual ICollection<Request> Requests { get; set; } = new List<Request>();
public virtual ICollection<UserRequest> UserRequests { get; set; } = new List<UserRequest();
}
public class User
{
// User properties...
// public virtual ICollection<Users> Users { get; set; } = new List<User>();
public virtual ICollection<UserRequest> UserRequests { get; set; } = new List<UserRequest();
}
public class UserRequest
{
[Key, ForeignKey("User"), Column(Order=0)]
public int UserId { get; set; }
[Key, ForeignKey("Request"), Column(Order=1)]
public int RequestId { get; set; }
public bool Flagged { get; set; }
public virtual User User { get; set; }
public virtual Request Request { get; set; }
}
这意味着改变 Users 和 Requests 之间的关系以通过 UserRequests 导航以相互联系。
即而不是:
foreach(var request in user.Requests)
{
// do stuff..
}
变成..
foreach(var userRequest in user.UserRequests)
{
var request = userRequest.Request;
// do stuff..
}
假设我们在 EF Core 中有以下具有以下导航属性的多对多关系场景:
public class Request{
public HashSet<User> Users { get; set; }
}
public class User{
public HashSet<Request> Requests { get; set; }
}
一个用户可能被简单地分配给多个请求,一个请求可能有多个用户。
现在,我想扩展功能,以便每个用户都能够标记他分配给的请求:
public class User{
public HashSet<Request> Requests { get; set; }
public Dictionary<long, bool> RequestsFlags { get; set; } //Request ID (long) and Flag (bool)
}
这样我就可以检查为哪个请求设置了标志并相应地更新 UI。问题是,这两个集合当然必须始终相互同步。
有没有办法确保自定义集合始终与导航保持一致属性?
如果不需要将标记请求的行为持久化到 UserRequest table,那么您可以考虑向名为“Flagged”的请求实体添加一个未映射的 属性。
即
public class Request
{
// normal mapped properties.
[NotMapped]
public bool Flagged { get; set; }
}
这里的限制是它只与已经加载的实体相关。您不能在 EF Linq 查询中使用它。如果用户和请求被投影到视图模型,那么这个 属性 最好在视图模型中提供。
如果您确实需要将标记状态保存到 UserRequest 记录,那么您需要将加入实体引入关系中:
public class User
{
// User properties...
// public virtual ICollection<Request> Requests { get; set; } = new List<Request>();
public virtual ICollection<UserRequest> UserRequests { get; set; } = new List<UserRequest();
}
public class User
{
// User properties...
// public virtual ICollection<Users> Users { get; set; } = new List<User>();
public virtual ICollection<UserRequest> UserRequests { get; set; } = new List<UserRequest();
}
public class UserRequest
{
[Key, ForeignKey("User"), Column(Order=0)]
public int UserId { get; set; }
[Key, ForeignKey("Request"), Column(Order=1)]
public int RequestId { get; set; }
public bool Flagged { get; set; }
public virtual User User { get; set; }
public virtual Request Request { get; set; }
}
这意味着改变 Users 和 Requests 之间的关系以通过 UserRequests 导航以相互联系。
即而不是:
foreach(var request in user.Requests)
{
// do stuff..
}
变成..
foreach(var userRequest in user.UserRequests)
{
var request = userRequest.Request;
// do stuff..
}