【问题标题】:Entity Framework 4.3.1 not populating child entities实体框架 4.3.1 不填充子实体
【发布时间】:2013-11-12 20:00:11
【问题描述】:

使用存储库模式,我有一个 T 类型的通用存储库 EFRepository(使用泛型)。

我有一个名为 AllIncluding 的方法,用于获取实体及其任何子实体:

public IQueryable<T> AllIncluding(params Expression<Func<T, 
                                  object>>[] includeProperties)
{
    IQueryable<T> query = _dbSet;
    foreach (var includeProperty in includeProperties)
    {
        query = query.Include(includeProperty);
    }
    return query;
}

在调用中使用以下语法:

_machineRepository.AllIncluding(machine => machine.InstalledOS, 
                                machine => machine.LicenceType, 
                                machine => machine.User);

我的机器类看起来像这样(省略了一些细节):

public class Machine
{
    public int MachineId { get; set; }

    public int InstalledOSId { get; set; }
    public InstalledOS InstalledOS { get; set; }

    public int LicenceTypeId { get; set; }
    public LicenceType LicenceType { get; set; }

    public int UserId { get; set; }
    public User User { get; set; }
}

我发现在我为机器实体呈现视图(使用 ASP.NET MVC 4 beta)时,未填充已安装的操作系统和许可证类型实体,它们似乎已实例化,但 ID为 0,其他属性为空。直接在 Machine 实体中,InstalledOSId 和 LicenceTypeId 属性填充了正确的 Id。

如果我将应用程序一直调试到 AllIncluding 方法,我可以看到构造的 SELECT 查询包含正确的表和连接,但仍然没有骰子。

我不确定它是否有任何后果,但我将 IQueryable 一直传递回控制器。我假设视图渲染(返回视图(结果))可以管理枚举?

【问题讨论】:

  • 几件事:1. 我不确定Expression&lt;Func&lt;T, object&gt;&gt; 中的object 是否受到EF 的赞赏。 2. 模型中的导航属性不是虚拟的。 3. 尝试在通话后创建一个 ToList(),并得到错误(如果你有错误)。
  • LicenceType和InstalledOS的PK真的也是int吗?
  • @mfussenegger,是的,所有实体的 Id 都是整数。
  • @Raphaël Althaus; 1. 脚手架生成的代码,你建议用什么替换它? 2. 我已经完成了所有实体中的所有子实体的虚拟化,3. 执行 ToList 不会产生错误,它只会给我一个没有加载子实体的机器列表。
  • 只是检查您的上下文是否包含 InstalledOS 和 LicenceType 实体的 DbSet 条目?

标签: c# entity-framework


【解决方案1】:

这是您在此处所说的内容的一个非常简单的实现 - 也许您可以将其与您必须找到的差异进行比较:

public class Machine
{
    public int MachineId { get; set; }

    public int InstalledOSId { get; set; }
    public InstalledOS InstalledOS { get; set; }

    public int LicenceTypeId { get; set; }
    public LicenceType LicenceType { get; set; }
}

public class InstalledOS
{
    public int InstalledOSId { get; set; }
}

public class LicenceType
{
    public int LicenceTypeId { get; set; }
}

public class Context : DbContext
{
    public DbSet<Machine> Machines { get; set; }
    public DbSet<LicenceType> LicenceTypes { get; set; }
    public DbSet<InstalledOS> InstalledOSs { get; set; }
}

public class Repository<T> where T : class
{
    private DbSet<T> _dbSet;
    public Repository(DbSet<T> dbset)
    {
        _dbSet = dbset;
    }

    public IQueryable<T> AllIncluding(params Expression<Func<T, 
                                      object>>[] includeProperties)
    {
        IQueryable<T> query = _dbSet;
        foreach (var includeProperty in includeProperties)
        {
            query = query.Include(includeProperty);
        }
        return query;
    }
}

class Program
{
    static void Main(string[] args)
    {
        Database.SetInitializer(new DropCreateDatabaseAlways<Context>());
        Context context = new Context();

        InstalledOS os1 = new InstalledOS();
        context.InstalledOSs.Add(os1);

        LicenceType l1 = new LicenceType();
        context.LicenceTypes.Add(l1);

        Machine m1 = new Machine
        {
            InstalledOS = os1, 
            LicenceType = l1
        };
        context.Machines.Add(m1);

        context.SaveChanges();

        Repository<Machine> repo = new Repository<Machine>(context.Machines);

        var query = repo.AllIncluding(m => m.InstalledOS, m => m.LicenceType);
        Machine m2 = query.First();

        Console.WriteLine(m2.InstalledOS.InstalledOSId);
        Console.ReadLine();

    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-31
    • 2013-11-26
    • 2013-08-09
    • 1970-01-01
    相关资源
    最近更新 更多