c# - 为什么这不起作用?

标签 c# mysql entity-framework-4 eager-loading

我将值传递到一个使用 foreach 循环来迭代集合的方法中。在循环中,从 Entity Framework 使用 Include 语句进行预加载。这是我传入的内容:

var exp = new Collection<Expression<Func<Foo,object>>>();

为什么当我使用这个时:

exp.Add(f => f.Bars.Select(b=> b.Employees.Select( e=> e.Position)));
exp.Add(f => f.Bars.Select(b=> b.Employees.Select( e=> e.Bank)));

并且 Employee、Position 和 Bank 都有字段 Name,这会混淆不同字段之间的 Name?例如,银行和职位的姓名字段中都会有员工的姓名。更明确地说,无论出于何种原因

在数据库中:

Employee.Name = "Jon";
Employee.Bank.Name = "World Bank";
Employee.Position.Name = "CEO";

来自的数据。包含:

Employee.Bank.Name == "Jon" //true
Employee.Position.Name == "Jon" //true

额外信息,接受 exp 的方法内部

DbSet<Foo> dbSet = context.Set<Foo>();
IQueryable<Foo> query = dbSet;

if (exp != null)
{
 foreach (var incProp in exp)
 {
  query = query.Include(incProp);
 }
}

我的代码是否做错了什么?

编辑

public class Foo
{
 public int FooId { get; set; }
 public virtual List<Bar> Bars { get; set; }
}

public class Bar
{
 public int BarId { get; set; }
 public virtual Foo Foo { get; set; }
 public int FooId { get; set; }
 public virtual List<Employee> Employees { get; set; }
}

public class Employee
{
 public int EmployeeId { get; set; }
 public int BarId { get; set; }
 public virtual Bar Bar { get; set; }
 public int BankId { get; set; }
 public virtual Bank Bank { get; set; }
 public int PositionId { get; set; }
 public virtual Position Position { get; set; }
 public string Name { get; set; }
}

public class Bank
{
 public int BankId { get; set; }
 public string Name { get; set; }
}

public class Position
{
 public int PositionId { get; set; }
 public string Name { get; set; }
}

最佳答案

我不认为问题出在您所显示的代码中。我根据您上面放置的内容创建了一个控制台应用程序,它输出数据库中的内容。这是该应用程序的全部内容:

namespace ExampleCF
{
    public class Foo
    {
        public int FooId { get; set; }
        public virtual List<Bar> Bars { get; set; }
    }

    public class Bar
    {
        public int BarId { get; set; }
        public virtual Foo Foo { get; set; }
        public int FooId { get; set; }
        public virtual List<Employee> Employees { get; set; }
    }

    public class Employee
    {
        public int EmployeeId { get; set; }
        public int BarId { get; set; }
        public virtual Bar Bar { get; set; }
        public int BankId { get; set; }
        public virtual Bank Bank { get; set; }
        public int PositionId { get; set; }
        public virtual Position Position { get; set; }
        public string Name { get; set; }
    }

    public class Bank
    {
        public int BankId { get; set; }
        public string Name { get; set; }
    }

    public class Position
    {
        public int PositionId { get; set; }
        public string Name { get; set; }
    }

    public class Model : DbContext
    {
        public DbSet<Foo> Foos { get; set; }
        public DbSet<Bar> Bars { get; set; }
        public DbSet<Employee> Employees { get; set; }
        public DbSet<Bank> Banks { get; set; }
        public DbSet<Position> Positions { get; set; }

        public Model()
        {
            Configuration.LazyLoadingEnabled = false;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Model context = new Model();
            var exp = new Collection<Expression<Func<Foo, object>>>();

            Foo foo = new Foo();
            Bar bar = new Bar();
            Employee emp = new Employee() { Name = "employee" };
            Bank bank = new Bank() { Name = "bank" };
            Position position = new Position() { Name = "position" };
            foo.Bars = new List<Bar>();
            foo.Bars.Add(bar);
            bar.Employees = new List<Employee>();
            bar.Employees.Add(emp);
            emp.Position = position;
            emp.Bank = bank;
            context.Foos.Add(foo);
            context.SaveChanges();

            exp.Add(f => f.Bars.Select(b => b.Employees.Select(e => e.Position)));
            exp.Add(f => f.Bars.Select(b => b.Employees.Select(e => e.Bank)));

            DbSet<Foo> dbSet = context.Set<Foo>();
            IQueryable<Foo> query = dbSet;

            if (exp != null)
            {
                foreach (var incProp in exp)
                {
                    query = query.Include(incProp);
                }
            }

            var first = query.ToList().FirstOrDefault();
            var firstEmp = first.Bars.First().Employees.First();
            Console.WriteLine(String.Format("{0} | {1} | {2}", firstEmp.Name, firstEmp.Bank.Name, firstEmp.Position.Name));
        }
    }

}

输出:员工 |银行|仓位

您是否还在查询中添加了其他内容,或者您​​是否以某种方式创建了匿名类型?

关于c# - 为什么这不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12825643/

相关文章:

c# - 防止将特定的类型层次结构用于泛型参数

c# - Unity Application Block,如何将参数传递给注入(inject)工厂?

mysql - 按匹配次数排序

linq - Entity Framework 4 (CTP 5) 并发

c# - 在 ASP.NET MVC 中使用破折号进行路由

c# - 鼠标双击仅在右键单击时触发

MySQL 5.7.14 社区服务器安装在 macOS 10.12 上卡住

php - 在代码中放置 <a> 标记时图像幻灯片显示错误

c# - 如何检查实体的创建日期是否已过 20 天?

entity-framework-4 - 指定的 LINQ 表达式包含对与不同上下文关联的查询的引用