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