2017-10-14 50 views
1

我使用实体框架代码优先,并遇到轻微问题。来自GUID的访问类

我有两个表这样:

User 
+--------+-----------+ 
| id | name | 
+--------+-----------+ 
| def789 | Bob Smith | 
+--------+-----------+ 

Actions 
+--------+--------------+-------------+ 
| id | grantedTo_id | details | 
+--------+--------------+-------------+ 
| abc123 | def789  | some detail | 
+--------+--------------+-------------+ 

假装3个标识字段用于此目的的GUID。

我的类看起来是这样的:

User 
{ 
public Guid id {get; set;} 
public string name {get; set;} 
} 

Actions 
{ 
public Guid id {get; set;} 
public User grantedTo {get; set;} 
public string details {get; set;} 
} 

我的问题是,由于该类grantedTo定义类型的用户,不返回任何在它从数据库(因为它的类型的Guid)。

因此,举例来说,如果我不喜欢简单的东西:

var action = db.Action.ToList() 
foreach (var a in db.Action) 
{ 
var user = a.GrantedTo 
} 

然后用户包含空。

我该如何去获取用户引用的用户名?

这些都是先完成代码,我没有对它们进行任何修改。是否有描述符或我应该使用的东西?我想我可以做这样的事情:

var action = db.Action.ToList() 
foreach (var a in action) 
{ 
var user = db.Users.Find(...???) 
} 

但我没有模糊的东西放在那里,因为GUID不回来。

+2

你的'Action'类应该有'public virtual user grantedTo {get; set;}'和'public Guid UserId {get;组; }'创建一个导航属性 - 参考[实体框架关系和导航属性](https://msdn.microsoft.com/en-us/library/jj713564(v = vs.113).aspx) –

+0

@StephenMuecke OP已经有'公共用户授予{{get;设置;}',这就够了。 '虚拟'和明确的FK属性都不需要*。 –

+1

由于您的'grantedTo'属性不是'virtual',它不能被延迟加载,您需要使用加载或显式加载来加载它。例如,。 'var action = db.Action.Include(a => a.grantedTo).ToList();'将填充列表中动作的'grantedTo'属性。 –

回答

3

正如Entity Framework Loading Related Entities文档主题中所述,EF支持三种方式来加载相关数据 - 预加载,延迟加载和显式加载。

由于grantedTo属性未标记为virtual,因此它不适用于延迟加载,这是EF自动加载相关数据的三种方法的唯一方法。而在另外两个EF中,只有通过您明确的要求才能做到这一点,而从另一方面来说,您可以更好地进行控制。

例如,使用Include方法(预先加载)

var action = db.Action.Include(a => a.grantedTo).ToList(); 

将填充在列表中的操作的grantedTo财产。

这样做的另一个好处是它与目前不支持延迟加载的EF Core兼容。

1

如果使用代码首先,你需要你的行动定义修改为:

public class Action 
{ 
    [Key] 
    public Guid ActionId { get; set; } 
    // ... 
    public Guid GrantedToId { get; set; } 
    [ForeignKey("GrantedToId")] 
    public virtual User GrantedTo { get; set; } 
    // ... 
} 

如果您正在使用EF6可以使用EntityTypeConfiguration来建立关系,而无需FK属性定义的:

public class ActionConfiguration : EntityTypeConfiguration<Action> 
{ 
    public ActionConfiguration() 
    { 
    ToTable("Actions"); 
    HasKey(x => x.ActionId); 

    HasRequired(x => x.GrantedTo) 
     .WithMany() 
     .Map(x => x.MapKey("GrantedToId")) 
     .WillCascadeOnDelete(false); 
    } 
} 

我对EF的偏好是使用实体类型配置,因为我更喜欢模式优先开发,它使我更好地控制如何设置映射。我不喜欢同时具有导航属性和FK属性,因为你在两个公共setter上。这留下了各种丑陋的场景,你可能有一个FK,但没有参考加载......或者当更改参考时如果FK字段不匹配会发生什么情况,或者设置FK而不更新参考。