实体框架核心,左连接
Posted
技术标签:
【中文标题】实体框架核心,左连接【英文标题】:Entity Framework Core, left join 【发布时间】:2021-11-18 08:07:36 【问题描述】:我有这三张桌子。
UserCredentials
表:
ID Username Password
------------------------
1 User1 1
2 User2 2
3 User3 3
4 User4 4
5 User5 5
Connection
表;这里User1
和User2
是UserCredentials.ID
列的外键:
ID User1 User2
------------------
1 1 2
3 1 3
5 1 4
7 1 5
9 2 5
11 3 4
UserDetails
表;这里ID
是UserCredentials.ID
列的外键
ID FullName Avatar LastSeen
---------------------------------------------------
1 User1 FullName 2 2021-09-09 00:38:00.000
2 User2 FullName 1 2021-09-09 01:38:00.000
3 User3 FullName 4 2021-09-24 04:38:00.000
4 User4 FullName 5 2021-09-24 18:38:00.000
5 User5 FullName 7 2021-09-24 06:40:00.000
DataContext 类:
namespace ChatWeb_MVC.DataModel
public partial class ChatWebAppContext : DbContext
private readonly string _connectionString;
public ChatWebAppContext(string connectionString)
_connectionString = connectionString;
public ChatWebAppContext(DbContextOptions<ChatWebAppContext> options)
: base(options)
public virtual DbSet<Connection> Connections get; set;
public virtual DbSet<UserCredential> UserCredentials get; set;
public virtual DbSet<UserDetail> UserDetails get; set;
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
if (!optionsBuilder.IsConfigured)
optionsBuilder.UseSqlServer(_connectionString);
protected override void OnModelCreating(ModelBuilder modelBuilder)
//Model creation code...
public partial class Connection
public Connection()
Messages = new HashSet<Message>();
public int Id get; set;
public int User1 get; set;
public int User2 get; set;
public virtual UserCredential User1Navigation get; set;
public virtual ICollection<Message> Messages get; set;
public partial class UserCredential
public UserCredential()
Connections = new HashSet<Connection>();
public int Id get; set;
public string Username get; set;
public string Password get; set;
public virtual Message Message get; set;
public virtual UserDetail UserDetail get; set;
public virtual ICollection<Connection> Connections get; set;
public partial class UserDetail
public int Id get; set;
public string FullName get; set;
public int Avatar get; set;
public DateTime LastSeen get; set;
public virtual UserCredential IdNavigation get; set;
internal ChatModel GetChatHistory(int userID)
ChatModel chat = new ChatModel();
chat.UserName = this.UserCredentials.FirstOrDefault(m => m.Id == userID).Username;
chat.UserID = userID;
List<ChatWeb_MVC.Models.UserDetail> connections = new List<ChatWeb_MVC.Models.UserDetail>();
// Problem
// I currently have login userID, by using It I want to get his/her friend's details and want to store them in `List<UserDetail> Connections`.
// For example, if the current login user ID is 3, then I want his friend [User ID: 1 and 4] details stored in `List<UserDetail> Connections`.
// I've tried this shown below, but I'm not getting the result I want:
var result = from conn in this.Connections
join userDetail in this.UserDetails on conn.User1 equals userDetail.Id into UserDetails
from m in UserDetails.DefaultIfEmpty()
where conn.User1 == userID || conn.User2 == userID
select new ChatWeb_MVC.Models.UserDetail
Id = m.IdNavigation.Id,
ConnectionID = conn.Id,
Username = m.IdNavigation.Username,
FullName = m.FullName,
Avatar = GetAvatar(m.Avatar),
LastSeen = m.LastSeen,
;
chat.Connections = result.ToListAsync().Result;
return chat;
这里我使用的查询没有给出我想要的结果。
数据模型类:
namespace ChatWeb_MVC.Models
public class ChatModel
public List<UserDetail> Connections get; set;
public string UserName get; set;
public int UserID get; set;
public class UserDetail
public int Id get; set;
public int ConnectionID get; set;
public string Username get; set;
public string FullName get; set;
public string Avatar get; set;
public DateTime LastSeen get; set;
【问题讨论】:
你共享的模型和表不一样... 这行conn.User1 equals userDetail.Id
好像有问题! User1 和 UserDetail.Id 一样吗?
@Transcendent 它可以是 Connection 表中 User1 User2 中的任何人。
查询中的ChatModel
在哪里?为什么在映射模型类中没有导航属性?
@GertArnold 我已经更新了代码。
【参考方案1】:
我发布了一个答案,但我想要一个查询而不是三个。 如果有人有更好的解决方案,请发布。
var friends = this.Connections.Where(m => m.User1 == userID).Select(m => new conID = m.Id, friendID = m.User2 ).ToListAsync().Result;
friends.AddRange(this.Connections.Where(m => m.User2 == userID).Select(m => new conID = m.Id, friendID = m.User1 ).ToListAsync().Result);
var result = from friend in friends
join userDetail in this.UserDetails on friend.friendID equals userDetail.Id into UserDetails
from m in UserDetails.DefaultIfEmpty()
select new ChatWeb_MVC.Models.UserDetail
Id = m.Id,
ConnectionID = friend.conID,
FullName = m.FullName,
Avatar = GetAvatar(m.Avatar),
LastSeen = m.LastSeen,
;
【讨论】:
以上是关于实体框架核心,左连接的主要内容,如果未能解决你的问题,请参考以下文章