因爲你沒有做什麼特別的東西在這裏(甚至沒有任何預測),您可以直接從上下文中返回實體,包括您想要的導航屬性:
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