2017-07-18 58 views
0

我有类似下面的类:实体框架代码优先布尔外键

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

不过,我想知道,如果实体框架可以照顾这对我来说。在我的脑海中,我可以想像它使用IsAdmin的方式类似于用于Users列表,其中具有User.GroupId = "foo"的每个用户都包含在Group.Id = "foo"组的Users列表中。

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

+0

你应该坚持财产'清单管理员'。当你已经有了一些可行的东西时,为什么复杂化呢?简单更好。 – JuanR

+0

由于管理员“是”用户,您可以使用[继承](http://www.entityframeworktutorial.net/code-first/inheritance-strategy-in-code-first.aspx) –

+0

*我想知道如果实体框架可以为我照顾这个*目前的答案没有明确说明它,但是这个问题的答案是“否”。 –

回答

0

所以首先,在这种情况下使用术语“外键”是错误的。 IsAdmin不是外键,充其量是鉴别者。

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

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

使EF忽略该属性,并且不尝试创建任何与它的关系,这样,你会得到你想要的值在您访问管理员时延迟加载。

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

重新阅读,你的问题,上述不适用,但是,我会留在这里,以防有人遇到类似的情况发生在这个答案。