【问题标题】:Entity Framework Include Parent Entities实体框架包括父实体
【发布时间】:2015-08-20 15:48:50
【问题描述】:

当我访问所有城市时,我的代码是这样的。

 public IQueryable<City> GetAll()
    {
        var result = from s in this.Context.Cities.Include("States.Countries") select s;
        return result;
    }

这工作正常,包括州和县。我想通过国家 ID 获取城市,下面是我的代码。在下面的代码中,我想包含每个城市的 States.Countires。我该怎么做?

public IEnumerable<City> GetByCountriesId(int Id)
    {
        var result = from s in this.Context.Countries
                     join a in this.Context.States on s.Id equals a.Country_Id
                     join b in this.Context.Cities on a.Id equals b.States_Id
                     where s.Id == Id 
                     select b;

        return result;
    }

【问题讨论】:

  • 如果CityState 具有适当的导航属性,this.Context.Cities.Include("State.Country").Where(c=&gt;c.State.Country.Id==Id) 就足够了。
  • 您使用的是什么版本的 EF?我问是因为您使用的带有字符串参数的 Include 较旧,您应该使用表达式方法来支持编译时。例如:'.Include(x => x.States)'

标签: c# linq entity-framework linq-to-entities


【解决方案1】:
public IEnumerable<City> GetByCountriesId(int id)
{
    return from country in this.Context.Countries
           where country.Id == id
           from state in country.States
           from c in this.Context.Cities.Include(c => c.States.Select(s => s.Countries))
           where c.States.Any(s => s == state)
           select c;
}

或者,甚至更好:

public IEnumerable<City> GetByCountryId(int id)
{
    return from c in this.Context.Cities
                     .Include(c => c.States.Select(s => s.Countries))
           where c.States.Any(s => s.Countries.Any(c => c.Id == id))
           select c;
}

然而——虽然很清楚为什么Country 有一个States 集合,而State 有一个Cities 集合——为什么你的City 有一个States 集合而你的State 有一个@987654330 @ 收藏?这些不应该分别是StateCountry 属性吗?

假设您的City 确实有一个State,而您的State 有一个Country,这将大大简化:

return from c in this.Context.Cities
                 .Include(c => c.State.Select(s => s.Country))
       where c.State.Country.Id == id
       select c;

【讨论】:

    【解决方案2】:

    您确定一个城市可以属于多个州吗?恕我直言,您应该有一对多的关系,其中State 可以有多个Cities,而City 应该属于一个StateStateCountry 也是如此。我认为您已经使这些导航多元化。属性名称(City 中的StatesCountry 中的Cities),但没有集合。如果您以我上面描述的相同方式拥有这两个一对多关系,您可以编写一个如下所示的查询来实现您所需要的:

     var result = this.Context.Cities.Include(c=>c.State.Country).Where(c=>c.State.Country.Id==Id‌​);
    

    最好使用DbExtensions.Include 扩展方法,因为它是强类型的。

    现在,也许您可​​以认为此查询可能以 NullReferenceException 结尾,因为 c.State.Country.Id 表达式以防万一。属性可能是null。但这不会发生,因为当您需要保存新的CityState DB,换句话说,它们是必需的

    如果你使用 Fluent Api 来配置这些关系,你会以这样的方式结束:

    modelBuilder.Entity<City>().HasRequired(c=>c.State).WithMany(s=>s.Cities).HasForeignKey(c=>c.State_Id);
    modelBuilder.Entity<State>().HasRequired(s=>s.Country).WithMany(c=>c.States).HasForeignKey(s=>s.Country_Id);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-06-21
      • 1970-01-01
      • 2017-03-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-07-12
      相关资源
      最近更新 更多