实体框架 - 仅从多个导航属性中检索特定列

时间:2014-04-17 16:31:50

标签: entity-framework viewmodel navigational-properties

我有一个Project实体,它具有导航属性ProjectNumbers,Addresses,Contacts和BBLInfos。我正在尝试仅选择每个导航属性的某些字段,并将它们存储在视图模型中。

视图模型如下所示:

public class PropertyInfoViewModel
{
    public ProjectViewModel Project { get; set; }
    public IQueryable<ProjectNumberViewModel> ProjectNumbers { get; set; }
    public IQueryable<AddressViewModel> Addresses { get; set; }
    public IQueryable<BBLInfoViewModel> BBLInfos { get; set; }
    public IQueryable<ContactsViewModel> Contacts { get; set; }
}

在Project DbSet上调用.Include不起作用,因为它包含完整的相关实体。

我能够通过分别查询每个相关表并选择ProjectId与项目匹配的实体来实现这一点,但这需要4个单独的表查询。是否有更有效的方法来获取相关实体,而只从相关实体中选择几列?

这就是我目前正在做的事情:

 PropertyInfoViewModel model = PropertyInfoViewModel.ViewModelSelector().Invoke(
    new Repository<Project>(epicContext).Get(id),
    new Repository<ProjectNumber>(epicContext).Get(projectNumber => projectNumber.ProjectId == id),
    new Repository<Address>(epicContext).Get(address => address.ProjectId == id),
    new Repository<BBLInfo>(epicContext).Get(bblInfo => bblInfo.ProjectId == id),
    new Repository<Contact>(epicContext).Get(contact => contact.ProjectId == id)

然后,ViewModelSelector仅选择所需的字段:

public class PropertyInfoViewModel
{
    public static Func<Project, IQueryable<ProjectNumber>, IQueryable<Address>, IQueryable<BBLInfo>, IQueryable<Contact>, PropertyInfoViewModel> ViewModelSelector()
    {
        return (project, projectNumbers, addresses, bblInfos, contacts, projectInfo) =>
            new PropertyInfoViewModel()
            {
                Project = project,
                ProjectNumbers = projectNumbers.Select(ProjectNumberViewModel.ViewModelSelector()).AsQueryable(),
                Addresss = addresses.Select(AddressViewModel.ViewModelSelector()).AsQueryable(),
                BBLInfos = bblInfos.Select(BBLInfoViewModel.ViewModelSelector()).AsQueryable(),
                Contacts = contacts.Select(ContactViewModel.ViewModelSelector()).AsQueryable(),
            };
    }

ViewModelSelector函数是这样我只需要编写一次linq查询的“.select”部分,然后我可以重用它们。内部ViewModelSelector方法仅选择特定字段,如下所示:

public static Func<Address, AddressViewModel> ViewModelSelector()
    {
        return address => new AddressViewModel()
        {
            ProjectId = address.ProjectId,
            AddressId = address.AddressId,
            StreetNumber = address.StreetNumber,
            StreetName = address.StreetName,
            ZipCode = address.ZipCode
        };
    }

谢谢!

0 个答案:

没有答案