显然,
Notification
对象具有
messageId
。几个
Notification
对象可能具有相同的
MessageId
值。
我想要获得一个子集所有Notification
对象中MessageId
值等于某个Id的Messages
。
首先我会向你展示一条LINQ查询语句来解决你的问题,然后我会告诉你一些关于实体框架的事情,这将使这种类型的LINQ查询更容易理解和维护。
直接解决方案
(1)选择应获取消息的通知:
IQueryable<Notification> notificationsToUse = org.Notifications
.Where(notification => notification.TypeId == 7
&& ....)
这是您的内部选择。我不确定
Notifications
,
OrgUsers
和
OrgRelations
之间的关系。但这超出了本问题的范围。
(2) 提取所有使用的
MessageIds
。
IQueryable<int> messageIdsUsedByNotificationsToUse = notificationsToUse
.Select(notification => notification.MessageId)
// remove duplicates:
.Distinct();
(3) 获取所有在`messageIdsUsedByNotificationsToUse`中的活动消息
IQueryable<Message> fetchedActiveMessages = org.Messages
.Where(message => message.IsActive
&& messageIdsUsedByNotificationsToUse.Contains(message.Id))
(4) 您不需要完整的消息,只需要 MessageId
和 Comment
:
var result = fetchedActiveMessages.Select(message => new
{
MessageId = message.Id,
Comment = message.Comment,
})
TODO: 如果需要的话:将它们组成一个大的LINQ语句。
到目前为止,您还没有访问数据库。 我只是改变了IQueryable中的Expression。 将其组成一个大的LINQ语句不会显著提高性能,我怀疑它是否会提高可读性和可维护性。
利用Entity Framework的可能性解决方案
似乎Message和Notification之间存在一对多关系:每个Message有零个或多个Notifications,每个Notification恰好属于一个Message,使用外键MessageId。
如果您坚持Entity Framework Code-First约定, 设计类类似于以下方式。(强调一对多关系):
class Message
{
public int Id {get; set;}
public virtual ICollection<Notification> Notifications {get; set;}
...
}
class Notification
{
public int Id {get; set;}
public int MessageId {get; set;}
public virtual Message Message {get; set;}
...
}
class MyDbContext : DbContext
{
public DbSet<Message> Messages {get; set;}
public DbSet<Notification> Notifications {get; set;}
}
这是Entity Framework所需了解的关于您在
Messages
和
Notifications
之间规划一对多关系的全部内容。Entity Framework 知道您打算将哪些属性用作主键和外键,以及表格之间的关系。
有时候有很好的理由要违反这些约定。这需要使用属性或流畅 API 来解决。
重要的是具有从
Message
到
Notification
的虚拟 ICollection 结构和从属于它的
Message
的
Notification
的虚拟引用返回。
如果您设计的类就像这样,那么查询将会非常简单:
(1)选择您想要使用的通知:
IQueryable<Notification> notificationsToUse = ... same as above
(2) 现在您可以直接选择属于这些通知的消息:
var result = notificationsToUse.Select(notification => notification.Message)
因为每个通知都属于唯一的一条消息,所以我确定没有重复。
继续说:只有活动消息的MessageId和Comment。
.Where(message => message.IsActive)
.Select(message => new
{
MessageId = message.Id,
Comment = message.Comment,
});
我不确定Notifications
、OrgUsers
和OrgRelations
之间的关系。如果您设计类来表示适当的一对多或多对多关系,那么即使是表达式(1)也会简单得多。