实体框架 CTP5 重新加载相关实体

Posted

技术标签:

【中文标题】实体框架 CTP5 重新加载相关实体【英文标题】:Entity Framework CTP5 Reload related entities 【发布时间】:2011-03-30 14:20:32 【问题描述】:

我正在考虑是否在我刚开始的新应用程序的开发中退出EF CTP5。

这是我的情况:

public class EnergieContext : DbContext, IEnergieContext

    public EnergieContext()
        : base("EnergieDatabase")
    
        this.Configuration.ProxyCreationEnabled = false;
    
protected override void OnModelCreating(DbModelBuilder modelBuilder)
    
        modelBuilder.Entity<RegionUser>()
            .Property(ru => ru.RegionUserID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
    

    public DbSet<Region> Regions  get; set; 
    public DbSet<RegionUser> RegionsUsers  get; set; 

public class Region

    public int RegionID  get; set; 
    public string Name  get; set; 

    public virtual ICollection<RegionUser> RegionUsers  get; set; 


public class RegionUser

    [Key]
    [Column(Order = 0)]
    public int RegionUserID  get; set; 

    [Key]
    [Column(Order = 1)]
    public int RegionID  get; set; 

    [Key]
    [Column(Order = 2)]
    public int ZicyzUserID  get; set; 

    public DateTime? DateAllocated  get; set; 

    public DateTime? DateRemoved  get; set; 

    public bool IsActive  get; set; 

    public virtual Region Region  get; set;        

    [NotMapped]
    public virtual Employee ZicyzUser  get; set; 

我的目标是过滤掉不活跃的用户,而不是从表中删除条目,我将已删除的用户标记为不活跃,即IsActive = false;...

我实现了这样的过滤:

public Region GetRegionDetails(int regionID)
    
        Region region = Regions.Where(r => r.RegionID == regionID).FirstOrDefault();

        Entry(region).Collection(r => r.RegionUsers).Query().Where(ru => ru.IsActive == true).Load();

        return region;
    

这将使用标记为IsActive = true 的所有RegionUser 实体填充RegionUsers 集合。这意味着那些标记为非活动的我们将无法获取:)

但是,如果我决定使用IsActive = false 更新任何RegionUser 实体,则更改会反映在RegionUsers 集合中,但问题是该集合仍然包含我希望过滤掉的项目。

我已经读到Entry(Regions).Reload() 应该从数据库中读取,不幸的是这并没有发生,我最终还是被那些不会离开的“非活动”项目卡住:(

请帮忙:)

谢谢!

Nermin.

【问题讨论】:

CTP5 版本过时。您应该使用 EF 4.1RC 嗨,Ladislav,实际上我使用的是 4.1 RC,抱歉误导:( 【参考方案1】:

没有。 Reload 将仅再次加载主实体,而不是其导航属性。导航属性已加载,并且不受重新加载父级的影响。

您可以尝试这样做(不确定是否有帮助):

var inactiveUser = GetInactiveUser(region);
context.Entry(inactiveUser).State = EntityState.Detached;

【讨论】:

这很酷,但我看不到它的作用?我正在尝试重新加载导航属性,即ICollection。最初,导航属性根本不会过滤。我要做的就是将这个this.Configuration.ProxyCreationEnabled = false; 告诉上下文的构造函数,以避免最初加载未过滤的导航道具。然后在我的GetRegionDetails(int regionID) 方法中我能够过滤,但只是第一次:( 也许Detached 属性可以与ICollection 一起发挥作用?! 我最终将ICollection 与实体Region 完全分离并手动加载集合。这是一种解决方法,但我仍在寻找有关如何重新加载相关实体的解决方案。

以上是关于实体框架 CTP5 重新加载相关实体的主要内容,如果未能解决你的问题,请参考以下文章

实体框架代码优先 CTP5:如何定义非原始类型

实体框架(CTP5、Fluent API)。重命名导航属性的列

实体框架 CTP5,代码优先。多对多级联删除

实体框架 4.1 DbSet 重新加载

实体框架6、加载实体async/await

如何使用代码优先实体框架在 ASP.Net MVC3 中重新加载多对多导航属性