实体框架代码 第一个布尔外键



我有一个这样的类:

public sealed class User 
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public string Id { get; private set; }
[Required] public string GroupId { get; set; }
[Required] public bool IsAdmin { get; set; }
}

另一个:

public sealed class Group
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public string Id { get; private set; }
[ForeignKey("GroupId")]
public List<User> Users { get; set; }
}

User类的IsAdmin属性表示用户是否为管理员。我想做的是添加一个新属性到Group

public List<User> Admins { get; set; }

此新列表将包含属于其组管理员的所有用户,这意味着其属性IsAdmin具有值true。我已经考虑过为此属性使用自定义 getter,如下所示:

public List<User> Admins
{
get
{
return this.Users.Where(user => user.IsAdmin);
}
}

但是,我想知道实体框架是否可以为我解决这个问题。在我的脑海中,我可以想象它以类似于GroupId用于Users列表的方式使用IsAdmin,其中每个具有User.GroupId = "foo"的用户都包含在具有Group.Id = "foo"的组的Users列表中。

所以我的问题是,我如何告诉 EF 使用用户的IsAdmin属性作为外键来填充Admins

因此,首先,在这种情况下使用术语"外键"是错误的。IsAdmin不是外键,充其量只是一个鉴别器。

其次,你可以像这样使用 [NotMapped] 属性

[NotMapped]    
public List<User> Admins
{
get
{
return this.Users.Where(user => user.IsAdmin);
}
}

以便 EF 忽略该属性并且不尝试与其创建任何关系,这样,您将在访问管理员时获得所需的延迟加载值。

最后,我认为你的数据结构都是错误的。除非用户只能是一个组的成员,或者作为一个组中的管理员使他们成为他们所属的所有组的管理员,否则您的结构从域角度来看是有意义的,但从数据角度来看仍然是错误的。 我建议您做的是将管理员<->用户关系视为多对多,并引入一个相交对象 GroupAdmins,该对象将具有组的 ID 和用户的 ID。您可以让 EF 自动创建该相交表,为您提供更简单的域模型,也可以手动执行此操作,请参阅此处的前者文章。

重新阅读,您的问题,上述内容不适用,但是,如果遇到类似情况的人遇到此答案,我将将其留在这里。

相关内容

最新更新