![](/img/trans.png)
[英]EF 6 codde first - One To Many Mapping - ICollection always null
[英]EF 6 - One To Many Mapping Always Null
我似乎無法解決我的映射問題; 關系是一個用戶可能有很多場地,場地必須有一個用戶。
我的venue
類看起來像:
public class Venue : BaseObject, IBaseObject
{
[Required]
public virtual User Owner { get; set; }
[Required]
[MaxLength(50)]
public string Name { get; set; }
}
我的User
類看起來像:
public class User : BaseObject, IBaseObject
{
[Required]
public string Name { get; set; }
[Required]
[DisplayName("Email")]
public string EmailAddress { get; set; }
[Required]
public string Password { get; set; }
public bool Active { get; set; }
public virtual ICollection<Venue> Venues { get; set; }
}
DbContextClass按要求
public class SystemContext : DbContext, IDbContext
{
public SystemContext() :
base("SystemContext")
{
Database.SetInitializer<SystemContext>(null);
Configuration.ProxyCreationEnabled = false;
Configuration.LazyLoadingEnabled = true;
}
public SystemContext(string connectionstringname = "SystemContext") :
base(connectionstringname)
{
Database.SetInitializer<SystemContext>(null);
Configuration.ProxyCreationEnabled = false;
}
public new IDbSet<T> Set<T>() where T : class
{
return base.Set<T>();
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<User>().HasMany(x=>x.Venues);
}
public DbSet<PublicQueries> PublicQueries { get; set; }
public DbSet<Venue> Venues { get; set; }
public DbSet<User> Users { get; set; }
}
當我從數據庫加載User
類時, Venues
似乎總是為空?
我以前做過類似的事,但不記得我是如何重新安排的。
謝謝
很確定這是一個懶惰的問題。 如果加載具有導航屬性的對象,例如ICollection<Venues>
則默認情況下不會包含它們,因為它們可能有更多導航屬性鏈接到更多對象,這些對象可能具有更多導航屬性...並且在您知道之前你加載了一半的數據庫。 當您在訪問該導航屬性時已經處理了對象出現的上下文時,這是一個特殊問題,因為它沒有數據庫連接來加載它們,即使它確實意識到它應該這樣做。
解決方法是通過添加.Include(u => u.Venues);
告訴實體框架您希望填充該屬性.Include(u => u.Venues);
當你從DbSet
獲取它們時。 您需要包含System.Data.Entity
以獲取Include()
特定重載。
您的venue
類還應該有一個名為OwnerId
的字段。
您可以將此鏈接作為參考作為延遲加載的開始。
public class Venue : BaseObject, IBaseObject
{
public (int/guid/or other type if you want) OwnerId{get;set;}
[Required]
public virtual User Owner { get; set; }
[Required]
[MaxLength(50)]
public string Name { get; set; }
}
然后還要確保您的User
類有一些Id
字段,然后由EF
用作外鍵
這就是我要做的,
public class Venue : BaseObject, IBaseObject
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id{get;set;}
public int OwnerId{get;set;}
[Required]
public virtual User Owner { get; set; }
[Required]
[MaxLength(50)]
public string Name { get; set; }
}
public class User : BaseObject, IBaseObject
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id {get;set;}
[Required]
public string Name { get; set; }
[Required]
[DisplayName("Email")]
public string EmailAddress { get; set; }
[Required]
public string Password { get; set; }
public bool Active { get; set; }
public virtual ICollection<Venue> Venues { get; set; }
}
public SystemContext() :
base("SystemContext")
{
Database.SetInitializer<SystemContext>(null);
Configuration.ProxyCreationEnabled = true;
Configuration.LazyLoadingEnabled = true;
}
在我的上下文中將“ProxyCreationEnabled”設置為true似乎已經解決了這個問題。
閱讀EF 4 - Lazy Loading Without Proxies后引用:
使用具有Entity Framework內置功能的POCO實體時,必須啟用代理創建才能使用延遲加載。 因此,對於POCO實體,如果ProxyCreationEnabled為false,則即使LazyLoadingEnabled設置為true,也不會發生延遲加載。
檢查你的數據庫,在Venue表中找到forginKey,看看它是否可以為null。
if可以為null,即0..N,如果不能為null,則為1..N
我想你想要一個1..N
1..N使用flunt api配置,使用代碼類似
modelBuilder.Entity<User>().HasMany(x=>x.Venues).WithRequired(x=>x.Owner);
如果您有保存用戶標識的屬性,則可以使用
modelBuilder.Entity<User>().HasMany(x=>x.Venues).WithRequired(x=>x.Owner).HasForeignKey(x=>x.userid);
或者ef將創建一個db字段
這些配置用戶,你也可以配置場地
modelBuilder.Entity<Venues>().HasRequired(x=>x.Owner).WithMany(x=>x.Venues).HasForeignKey(x=>x....)
它做同樣的事情
如果你想要一個0..N,你可以將HasRequired / WithRequired更改為HasOptional / WithOptional
db字段可以為null
我仍然不確定為什么會發生這種情況(這可能是為了獲得更好的性能......)但你必須自己加載屬性。
所以在你的情況下,它看起來像這樣:
// Load the user from the database
User user = await UserDataContext.Users.SingleOrDefaultAsync(u => u.Id == "UserID");
// Then load in all the venues
await UserDataContext.Entry(user).Collection(u => u.Venues).LoadAsync();
// Now you could access the venues
foreach (var venue in user.Venues) Console.WriteLine(venue);
在一對一映射情況下,只需使用Reference
方法加載屬性:
await UserDataContext.Entry(user).Reference(u => u.Venue).LoadAsync();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.