EF5和Lambda / Linq - 如何仅包含相关表的某些列

时间:2012-12-11 16:32:16

标签: c# linq entity-framework lambda

我的存储库中有一个方法来检索项目的所有记录

public IQueryable<Item> GetAll()
        {
            //The following causes a circular reference if you attempt to serialize it via an API call.
            IQueryable<Item> items = context.Items.Include(c => c.UserProfile).Include(c => c.UserProfile1).AsQueryable();
            return items;
        }

这导致了Kendo Grid和序列化的问题,因为我如何包括外部表User Profile两次,以便能够获得创建和修改Item记录的用户的全名。

而不是Include(c => c.UserProfile)是否只能包含UserProfile.FullName列?

今天我在我的ViewModel中处理这个并创建一个新的子类(这个例子是针对Locations而不是Items):

public class LocationsListViewModel
    {
        public IEnumerable<LocationsGrid> Locations { get; set; }
        public IEnumerable<Facility> Facilities { get; set; }
        public IEnumerable<string> AreaOptions { get; set; }
        public int LocationCount { get; set; }

        public class LocationsGrid
        {
            public int Id { get; set; }
            public string DisplayLocation { get; set; }
            public string Area { get; set; }
            public string Zone { get; set; }
            public string Aisle { get; set; }
            public string Bay { get; set; }
            public string Level { get; set; }
            public string Position { get; set; }
            public string Barcode { get; set; }

        }
    }

然后必须在我的任务或应用服务层(位于控制器和存储库之间)填充它,如下所示:

viewModel.Locations = from l in locations.ToList()
select new LocationsListViewModel.LocationsGrid
{
   Id = l.Id,
   DisplayLocation = l.DisplayLocation,
   Area = l.Area,
   Zone = l.Zone,
   Aisle = l.Aisle,
   Bay = l.Bay,
   Level = l.Level,
   Position = l.Position,
   Barcode = l.BarcodeValue
};

这似乎为每个实体提供了许多额外的代码和维护。我确信有更有效的方法可以做到这一点。

1 个答案:

答案 0 :(得分:1)

我通常使用数据传输对象(基本上只是一个具有您正在寻找的确切数据的类,然后从您的数据访问方法返回该类型的对象。

    public IQueryable<ItemSummary> GetAll()
    {
        IQueryable<ItemSummary> items = context.Items
            .Select(c => new ItemSummary {
                   FirstProfileName = c.UserProfile.FullName,
                   SecondProfileName = c.UserProfile1.FullName,
                   ScalarProp1 = c.ScalarProp1,
                   ...
                })
            .AsQueryable();
        return items;
    }

我不确定这是否会按照你想要的方式工作,因为我不熟悉Kendo Grid等,但它可能很有用。