从GUID访问类

时间:2017-10-14 04:26:02

标签: c# asp.net-mvc entity-framework

我正在使用Entity Framework Code First并遇到了一个小问题。

我有两张桌子:

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

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

假设3 Id字段是用于此目的的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定义为User类型,因此它不会从数据库中返回任何内容(因为它是Guid类型)。

例如,如果我做一些简单的事情:

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

然后用户包含null。

如何获取Id引用的用户?

这些是先完成的代码,我没有修改它们。是否有描述符或我应该使用的东西?我以为我可以这样做:

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

但是,由于GUID也没有回来,所以我不知道该放什么。

2 个答案:

答案 0 :(得分: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 :(得分:1)

如果您使用Code First,则需要将Action定义更改为:

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属性,因为您在两者上都有公共设置器。这会留下各种丑陋的场景,你可能有FK,但没有加载引用......或者当更改引用时,如果FK字段不匹配会发生什么,或者你设置FK而不更新引用。