因为你没有做什么特别的东西在这里(甚至没有任何预测),您可以直接从上下文中返回实体,包括您想要的导航属性:
eg考虑到这些实体:
class User
{
public string username { get; set; }
public ICollection<Connection> Connections { get; set; }
}
class Connection
{
public string ConnectionId { get; set; }
public string RoomName { get; set; }
}
一到一对多的关系应用户之间存在于数据库中 - >连接
为了获得特定用户的所有连接所有用户的所有连接,或者,或者你能想到的与同时保留您只需在System.Data.Entity
签名使用.Include()
从QueryableExtensions
关系的用户/连接过滤器/集料等查询的任意组合是这样,如果你有兴趣:
public static IQueryable<T> Include<T, TProperty>(this IQueryable<T> source, Expression<Func<T, TProperty>> path) where T : class
大约是EF一件好事,你可以渴望按需加载的子实体,而不必惹实体设计或添加不包含导航性能的新实体类
所以基本上它归结为:
using(YourDbContext context = new YourDbContext())
{
var query = context.Users.Include(user => user.Connections);
// Do stuff with query
}
不要忘了延迟执行 - 如果你不知道延迟执行是什么,查询是如何建立起来的EF这是值得它 - 在一般的经验法则是;查询数据库的次数越少,在C#中执行的处理越少(对于聚合数据库类型的操作)应用程序执行的速度越快 - 因此,确保在完全构建查询之前不要枚举结果或者你将要使用LINQ to对象在.NET端进行所有的数字处理,而不是在SQL中它应该是的!
所以调用.ToList()
或枚举上面的查询会得到你的结果
EF会翻译任何你已经使用你所选择的供应商(可能System.Data.SqlClient
)做了正确的SQL方言。你不需要写任何SQL ...
查询的其他一些例子,你可以这样做:
// Get me users called Fred including their connection details
context.Users.Include(x => x.Connections).Where(u => u.Username == "Fred")
// Get me users that are currently connected to "Game Room"
context.Users.Include(x => x.Connections).Where(u => u.Connections.Any(c => c.RoomName == "Game Room")
无的,这需要你写任何SQL - 把运行这些查询时看到EF做什么在SQL跟踪,通常会写查询比你曾经可能:)(仅有时没有,它通常是当你正在做一些愚蠢的)
编辑
好,我看你是想筛选的用户和通过导线回来的连接,在这种情况下,您需要将导航属性明确加载为单独的查询,或使用投影进行过滤。
显式加载
var user = context.Users.First(x => x.UserName == username);
context.Entry(user).Collection(x => x.Connections).Query().Where(x => x.RoomName == roomName).Load();
这也导致两个查询
投影
var usersConnections = context.Users
.Where(u => u.UserName == userName)
.Select(u => new
{
User = u,
Connections = u.Connections.Where(c => c.RoomName == roomName)
});
这导致含有User
属性一个匿名类型和Connections
财产。您可以随时投射到一个已知类型太多,如果你需要通过某种域边界的
这将是对数据源的单一查询发送此
,我不认为你可以返回与SqlQuery类子对象,除非你使用延迟加载。 – DavidG
我认为sql查询可以通过一种方式进行修改,使得完美的转换可能像是子查询或其他东西。 – pmbanugo
我不这么认为。 – DavidG