C# 如何集成查询存储库中多个实体并向视图发送数据的Linq到实体查询?

C# 如何集成查询存储库中多个实体并向视图发送数据的Linq到实体查询?,c#,entity-framework,linq-to-entities,repository-pattern,C#,Entity Framework,Linq To Entities,Repository Pattern,我正在学习MVC、存储库模式和EF,我需要一些关于如何最好地将包含查询多个实体的查询的方法集成到存储库中的建议 目前,我已经创建了一个repository类,它实现了一个接口,并使用一个DbContext实例使用Entity框架从数据库检索数据,但只针对一个实体 编辑。。。 我的存储库中有GetJourneys()方法,但是我不确定如何从Controller中的查询中获取旅程详细信息。我可以得到用户的详细信息 public IEnumerable<User> GetJourneys(

我正在学习MVC、存储库模式和EF,我需要一些关于如何最好地将包含查询多个实体的查询的方法集成到存储库中的建议

目前,我已经创建了一个repository类,它实现了一个接口,并使用一个DbContext实例使用Entity框架从数据库检索数据,但只针对一个实体

编辑。。。 我的存储库中有GetJourneys()方法,但是我不确定如何从Controller中的查询中获取旅程详细信息。我可以得到用户的详细信息

public IEnumerable<User> GetJourneys()
    {
        var todayDate = DateTime.Now;

        //Woking with many to many Relationship 
        //(join tables) in Asp.net MVC/Entity Framework
        var viewModel = from j in dbContext.Users
                        from u in dbContext.Journeys
                        where u.DepartDate >= todayDate.Date
                        orderby u.DepartDate ascending
                        select j;

        return viewModel.ToList();
    }
如何最好地将包含查询多个实体的查询的方法集成到存储库中

考虑到
用户
旅程
之间的关系,您应该决定哪个实体拥有该关系,并使用
聚合根
获取数据

对处的
Aggregate Root
的描述会有所帮助

更新:

实体

public class User
{
    public User()
    {
        this.Journeys = new List<Journey>();
    }

    public int Id { get; set; }
    public virtual IList<Journey> Journeys { get; set; }
}

public class Journey
{
    public Journey()
    {
        this.Users = new List<User>();
    }

    public int Id { get; set; }
    public virtual IList<User> Users { get; set; }
}
控制员的行动

public ViewResult Search()
{
    // Use UserRepository or JourneyRepository to make a list of
    // UserJourneyViewModel that provides appropriate data for the view.  
}

如果您正在尝试将所有用户行程展平到一个列表中(假设基于您传递到视图的模型的形状),则一种方法如下:

var userJourney = repository.GetAllUsersWithJourneys();
var searchView = new List<SearchViewModel>();
try
{   
    if (userJourneyList.Any())
    {
        foreach (var user in userJourney)
        {
            foreach(var journey in user.Journeys)
            {
                searchView.Add(new SearchViewModel()
                    {
                        UserName = user.FirstName,
                        JourneyDestination = journey.JourneyDestination
                    });                
            }
        }
    }
}
 catch (NullReferenceException ex)
 {
     // ... 
 }
如果存储库返回
IQueryable
而不是调用
ToList()
并返回
IList
,那么第二种方法会更好,但是不能与存储库一起立即处理
DbContext
。目前(使用
ToList()
),您将在内存中完成比让SQL完成更多的处理。如果存储库知道
SearchViewModel
,则可以执行以下操作:

public IList<SearchViewModel> GetSearchViewModels()
{
    using (var db = new EfDbContext())
    {
        var users = from user in db.Users
                    from journey in user.Journeys
                    select new SearchViewModel()
                    {
                        UserName = user.FirstName,
                        JourneyDestination = journey.JourneyDestination
                     }
                    select userJourney;

        return users.ToList();
    }
} 
public IList GetSearchViewModels()
{
使用(var db=new EfDbContext())
{
var users=来自数据库中的用户。users
从用户中的旅程。旅程
选择新的SearchViewModel()
{
用户名=user.FirstName,
JourneyDestination=旅程。旅程目的地
}
选择用户旅程;
返回users.ToList();
}
} 

但是,根据您的体系结构有多严格,这可能是演示层和数据层不可接受的混合。

用户和旅程之间的概念关系是什么?多对多是第二个“控制器”代码块中的关系,在注释为“错误”的行中,看起来您正在将类型为
ICollection
的值分配给类型为
string
的属性。这就是你的代码吗?@SteveRuble我更新了你描述的那行代码。我在上面包含了我的用户实体。用户将是根用户。我尝试将关系更改为一对一关系,只是想看看是否可以从控制器中的查询中获取旅程数据,我成功了。由于关系是多对多的,我的用户实体是否有问题,以及如何从与旅程详细信息相关的查询中获取数据。我认为
Search
方法实际上不是搜索,它会获取所有用户的旅程。我说的对吗?是的,这只是行动的名称。好的,我会用我的多对多关系解决方案更新答案。我希望,这会有帮助。谢谢你的贡献。但是,在获取所有用户(包括旅程)时,我仍然无法获取旅程数据。我根据你的反馈编辑了我的原始问题。谢谢史蒂夫的帮助,但没有成功。我的目标是读取所有旅程及其用户,并在视图的列表中显示。用户和旅程之间存在多对多关系。使用即时加载来获取数据是否正确?@ColinRoe,出了什么问题?是的,在这种情况下应该使用即时加载。我在控制器中调用了getAllUserSwithJournes方法,但我没有从查询中获得任何旅程数据。当我尝试在foreach循环中为SearchViewModel中的属性赋值时,我无法访问旅程属性(例如,JourneyDestination=Journey.ToDestination),因为它们目前不包含任何内容。GetAllUserSwithJournies方法中的急切加载以及如何访问控制器中的数据是否存在问题?
public class SearchViewModel
{
    public string ProfileImage { get; set; } //User
    public string JourneyDestination { get; set; } //Journey
    public DateTime JourneyDate { get; set; } //Journey
    public string UserName { get; set; } //User
    public int SeatsAvailable { get; set; } //Journey
    public bool UserType { get; set; } //Journey
}
public class User
{
    public User()
    {
        this.Journeys = new List<Journey>();
    }

    public int Id { get; set; }
    public virtual IList<Journey> Journeys { get; set; }
}

public class Journey
{
    public Journey()
    {
        this.Users = new List<User>();
    }

    public int Id { get; set; }
    public virtual IList<User> Users { get; set; }
}
public class UserRepository
{
    public IList<User> GetAllUsersWithJourneys()
    {
         //Fetch all Users; Include Journeys 
    }
}

public class JourneyRepository
{
    public IList<Journey> GetAllJourneysWithUsers()
    {
         //Fetch all journeys; Include Users 
    }
}
public class UserJourneyViewModel
{
    public int UserId { get; set; }
    public int JourneyId { get; set; }
}
public ViewResult Search()
{
    // Use UserRepository or JourneyRepository to make a list of
    // UserJourneyViewModel that provides appropriate data for the view.  
}
var userJourney = repository.GetAllUsersWithJourneys();
var searchView = new List<SearchViewModel>();
try
{   
    if (userJourneyList.Any())
    {
        foreach (var user in userJourney)
        {
            foreach(var journey in user.Journeys)
            {
                searchView.Add(new SearchViewModel()
                    {
                        UserName = user.FirstName,
                        JourneyDestination = journey.JourneyDestination
                    });                
            }
        }
    }
}
 catch (NullReferenceException ex)
 {
     // ... 
 }
var userJourney = repository.GetAllUsersWithJourneys();
var searchView = userJourney.SelectMany(
    user => user.Journeys.Select(
        journey => new SearchViewModel()
            {
                UserName = user.FirstName,
                JourneyDestination = journey.JourneyDestination
            }
        )
    )
    .ToList();        

if (!searchView.Any())
{
    // no results logic
}
public IList<SearchViewModel> GetSearchViewModels()
{
    using (var db = new EfDbContext())
    {
        var users = from user in db.Users
                    from journey in user.Journeys
                    select new SearchViewModel()
                    {
                        UserName = user.FirstName,
                        JourneyDestination = journey.JourneyDestination
                     }
                    select userJourney;

        return users.ToList();
    }
}