2017-10-14 90 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而不更新參考。