对于以下内容(我正在使用EF4),我需要选择一个线程中的所有消息( ContactThreadId ),这些消息在给定LoginId时尚未读取
所以,我基于ContactThreadId和LoginId,我需要知道这个LoginId是否已经读取了Thread中的所有消息。如果不是,我需要使用他/她的LoginId更新 ContactReadState 以及来自线程的所有消息以及何时阅读。
我尝试了这些但是被卡住了:
// Update read state
var thread = this.contactMessageThreadRepository.GetRow(id);
var loginEntity = this.loginRepository.GetRow(ProfileContext.LoginId);
var unreadMsg = loginEntity.Contact
.Where(x => x.ContactThread.Any(y => y.ContactThreadId == id))
.Select(b => b.ContactMessage.FirstOrDefault())
.Where(q => q.ContactReadState.Count() == 0);
var unreadMsg = loginEntity.Contact
.Where(x => x.ContactThread.Any(y => y.ContactThreadId == id))
.Where(y => y.ContactReadState.Any(q => q.ContactId != loginEntity.ContactId));
var msg = thread.Contact
.Where(x => x.LoginId == loginEntity.LoginId)
.Where(y => y.ContactReadState.Count() == 0);
请帮忙。 感谢
编辑:
登录 - 此表记录了登录/管理记录
联系 - 此表包含所有联系人(包括登录项,因为登录也可以参与对话 - 可以回复邮件等)当 LoginId时在联系人表中 NOT NULL ,这意味着它是登录用户,否则它是公共用户提交邮件。
问题 - >每个登录只能包含1个联系人记录(我有一个触发器,可在登录创建时创建联系记录) 。我该怎么做才能让它为1比1。 我已经从联系添加了一个FK到登录表,但由于某种原因,EF创建了0..1 - > *协会。它应该是1到1.对于给定的登录,只能有1个与LoginId的联系。
每当Login正在查看消息列表时,会向该Login的ContactReadState插入一条新记录(标记该Login读取的消息(使用ContactId进行该登录)。
答案 0 :(得分:2)
我有一个片段,但不能完全放在一起。特别是我不知道如何在新的ContactId
对象中设置ContactReadState
(请参阅下面的 ??? ),因为显然某个loginId
可能有很多联系人。那么,在新的读取状态中设置哪一个?可能我误解了你模型中的某些东西,因为所有这些关系对我来说都很复杂。
...基于 contactThreadId 和 loginId ......
我正在直接使用上下文,您需要将其转换为您的存储库结构:
using (var context = new MyContext())
{
var unreadMsgs = context.ContactMessages
.Where(cm => cm.ContactThreadId == contactThreadId
&& !cm.ContactReadState
.Any(crs => crs.Contact.LoginId == loginId))
.ToList();
// These should be the unread messages you want to select.
// Now, updating ContactReadState:
foreach(var unreadMsg in unreadMsgs)
{
var newContactReadState = new ContactReadState
{
ContactMessageId = unreadMsg.ContactMessageId,
ContactId = ???,
ReadDate = DateTime.Now
};
context.ContactReadStates.AddObject(newContactReadState);
}
context.SaveChanges();
}
修改强>
如果我理解正确,可以在没有登录的情况下联系,但如果有登录则会将其唯一分配给联系人。
在EF中正确创建这样的一对一关系需要以下内容:
LoginId
表中删除Contact
列和相应的关系(这是EF创建的一对多关系的原因)。LoginId
表中的Login
主键列不得为自动生成的标识。Contact
和Login
表之间创建外键关系,其中Login
中的外键列同时是主键列LoginId
。因此,关系介于Login.LoginId
(与FK“相关”)和Contact.ContactId
(与PK的“主体”)之间。这意味着Login
LoginId=x
引用Contact
ContactId=x
(相同值),最终可以轻松填充???
在上面的代码段中:???
只是= loginId
。
修改2
...当然你可以在查询中替换...
.Any(crs => crs.Contact.LoginId == loginId)
... ...通过
.Any(crs => crs.ContactId == loginId)
(这避免了对Contact
表的unnessacary连接)