1

条件付きインクルードを使用しようとしています(ここで説明しますが、子情報を取得していません。なぜですか?すべての手順を実行したと思います...WebApiコントローラーとVisualStudio2012を使用しています

私はすでにチェックしました、そして私は各家に割り当てられたdoorTypesを持っています。それは多対多の関係です。

私はこれを持っています:

DoorTypeにはこのプロパティがあります

public virtual ICollection<House> Houses{ get; set; }

家にはこのプロパティがあります

public virtual ICollection<Door> DoorTypes{ get; set; }

そして、私はこのメソッドをクエリしています

public IEnumerable<House> GetList(string latitude, string longitude, string idHousesTypeList)
{
    IEnumerable<int> intIds = null;

    if (!string.IsNullOrEmpty(idHousesTypeList))
    {
        var ids = idHousesTypeList.Split(',');
        intIds = ids.Select(int.Parse);
    }

    var location = DbGeography.FromText(string.Format("POINT ({0} {1})", latitude, longitude), 4326);
    var count = 0;
    var radius = 0.0;
    IEnumerable<House> houses = null;

    while (count < 5 && radius < 500)
    {
        radius += 2.5;
        var radiusLocal = radius;

        var dbquery =
            from house in Uow.Houses.GetAll()
            where house.Location.Distance(location) / 1000 <= radiusLocal
            orderby house.Location.Distance(location)
            select new
            {
                house,
                doorTypes= from doorType in house.DoorTypes
                                where intIds.Contains(doorType.Id)
                                select doorType
            };


        houses = dbquery
        .AsEnumerable()
        .Select(p => p.house);

        count = houses.Count();
    }

    if (houses != null && houses.Any())
    {
        return houses;
    }

    throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound));
}

一般的なEFRepositoryを使用しています

public class EFRepository<T> : IRepository<T> where T : class
{
    public EFRepository(DbContext dbContext)
    {
        if (dbContext == null)
            throw new ArgumentNullException("dbContext");
        DbContext = dbContext;
        DbSet = DbContext.Set<T>();
    }

    protected DbContext DbContext { get; set; }

    protected DbSet<T> DbSet { get; set; }

    public virtual IQueryable<T> GetAll()
    {
        return DbSet;
    }

    public virtual IQueryable<T> GetAllIncluding(params Expression<Func<T, object>>[] includeProperties)
    {
        IQueryable<T> query = DbContext.Set<T>();
        foreach (var includeProperty in includeProperties)
        {
            query = query.Include(includeProperty);
        }

        return query;
    }

    public virtual T GetById(long id)
    {
        return DbSet.Find(id);
    }

    public virtual IQueryable<T> GetByPredicate(System.Linq.Expressions.Expression<Func<T, bool>> predicate)
    {
        IQueryable<T> query = DbContext.Set<T>().Where(predicate);
        return query;
    }

    public virtual IQueryable<T> GetByPredicateIncluding(System.Linq.Expressions.Expression<Func<T, bool>> predicate, params Expression<Func<T, object>>[] includeProperties)
    {
        IQueryable<T> query = DbContext.Set<T>().Where(predicate);
        foreach (var includeProperty in includeProperties)
        {
            query = query.Include(includeProperty);
        }

        return query;
    }

    public virtual void Upsert(T entity, Func<T, bool> insertExpression)
    {
        if (insertExpression.Invoke(entity))
        {
            Add(entity);
        }
        else
        {
            Update(entity);
        }
    }

    public virtual void Add(T entity)
    {
        DbEntityEntry dbEntityEntry = DbContext.Entry(entity);
        if (dbEntityEntry.State != EntityState.Detached)
        {
            dbEntityEntry.State = EntityState.Added;
        }
        else
        {
            DbSet.Add(entity);
        }
    }

    public virtual void Update(T entity)
    {
        DbEntityEntry dbEntityEntry = DbContext.Entry(entity);
        if (dbEntityEntry.State == EntityState.Detached)
        {
            DbSet.Attach(entity);
        }
        dbEntityEntry.State = EntityState.Modified;
    }

    public virtual void Delete(T entity)
    {
        DbEntityEntry dbEntityEntry = DbContext.Entry(entity);
        if (dbEntityEntry.State != EntityState.Deleted)
        {
            dbEntityEntry.State = EntityState.Deleted;
        }
        else
        {
            DbSet.Attach(entity);
            DbSet.Remove(entity);
        }
    }

    public virtual void Delete(int id)
    {
        var entity = GetById(id);
        if (entity == null) return; // not found; assume already deleted.
        Delete(entity);
    }
}

出力にはすべての家が正しく表示されますが、doorTypesの配列は空です。私は何が欠けていますか?

4

2 に答える 2

1

それは多対多の関係です。

それが問題です。リレーションシップフィックスアップは、多対多の関係では機能せず、1対1または1対多の関係でのみ機能します。

クエリの実行後、ナビゲーションプロパティを手動で作成する必要があります。ただし、この場合は比較的簡単に実行できます。

houses = dbquery
    .AsEnumerable()
    .Select(p => {
        p.house.DoorTypes = p.doorTypes;
        return p.house;
    });

ナビゲーションコレクションのコンテキストへの明示的なロードが多対多の関係で機能しないのと同じ理由です。次の質問を参照してください。EF4.1フィルタリングされた子コレクションのロードが多対多で機能しないことと、その答え、特に主題についてのより深い背景のための関係の修正についてのZeeshanHiraniの説明への参照。

于 2013-01-11T18:06:13.033 に答える
0

Uow.Houses.GetAll()実装方法は明確ではありませんが、コンテキストからすべての家を取得する場合は、結果に含めるようにしてください。 DoorTypes

return context.Houses.Include("DoorTypes");

idHousesTypeLisまた、既存のIDで渡していることを確認してください。

更新:IncludeDbQueryのメンバーです。Setをにキャストすると使用できなくなりますIQueriable<T>。だから、これを試してみてください:

public class HouseRepository : EFRepository<House>
{
    public override IQueryable<House> GetAll()
    {
        return DbContext.Set<House>().Include("DoorTypes");
    }
}
于 2013-01-11T07:05:55.340 に答える