我在这方面工作了一个多星期,目前已退出压力, 希望你们能让我摆脱困境。 我欢迎如果您也可以建议整体不同的方法。好的,我们走了,
我在学习曲线上使用SignalR,MVC,JSON,jquery创建一个小型聊天应用程序。
我有Chatter类,其中包含ChatMsg类(Msgs)列表。正如下面的GetData()方法所示,我将我的类从数据库填充到列表中。正如您所见,Chatter列表包含一些变量,包括ChatMsg列表。这将对Table(新聊天消息)进行任何更改。 到目前为止,这个工作正常。 [添加部分]
[Serializable]
public class Chatter
{
public string Name { get; set; }
public bool Open { get; set; }
public DateTime LastMsg { get; set; }
public IEnumerable<ChatMsg> Msgs { get; set; }
}
[Serializable]
public class ChatMsg
{
public DateTime MsgCreated { get; set; }
public string MsgType { get; set; }
public string MsgBody { get; set; }
}
public List<Chatter> GetData()
{
Dictionary<string, List<ChatMsg>> dcm = new Dictionary<string, List<ChatMsg>>();
List<Chatter> lcm = new List<Chatter>();
using (var connection = new SqlConnection(_connString))
{
connection.Open();
using (var command = new SqlCommand(@"SELECT [Sender], [Receiver], [Body], [MessageCreated] FROM [dbo].[Chat] WHERE [Receiver] = @Name AND [Seen] = @Seen", connection))
{
command.Parameters.Add(new SqlParameter("@Name", "Fan"));//Test val
command.Parameters.Add(new SqlParameter("@Seen", "0"));//Test val
command.Notification = null;
var dependency = new SqlDependency(command);
dependency.OnChange += new OnChangeEventHandler(dependency_OnChange);
if (connection.State == ConnectionState.Closed)
connection.Open();
var reader = command.ExecuteReader();
while (reader.Read())
{
List<ChatMsg> cm = new List<ChatMsg>();
cm.Add(item: new ChatMsg { MsgCreated = Convert.ToDateTime(reader["MessageCreated"]), MsgType = "from", MsgBody = (string)reader["Body"] });
if (dcm.ContainsKey((string)reader["Sender"]))
{ dcm[(string)reader["Sender"]].Add(item: new ChatMsg { MsgCreated = Convert.ToDateTime(reader["MessageCreated"]), MsgType = "from", MsgBody = (string)reader["Body"] }); }
else { dcm.Add((string)reader["Sender"], cm); }
}
}
}
foreach (KeyValuePair<string, List<ChatMsg>> pair in dcm)
{
lcm.Add(item: new Chatter { Name = pair.Key, Open = true, LastMsg = DateTime.UtcNow, Msgs = pair.Value });
}
// Updateting [Seen] = 1 here
return lcm;
}
现在,如果这是一个新实例,我将这个聊天列表放到会话中。
每当getData()获取新数据时,我都想检查我的会话[&#34; ChatHistory&#34;]如果Parent.Name存在,我想更新Parent和Addrange to Msgs,如果不是来自getData()会话列表的ad new parent。 我正在喋喋不休地谈论以下代码。
public string receiveMessages()
{
if (Session["ChatHistory"] == null) Session["ChatHistory"] = new List<Chatter>();
List<Chatter> lc = (List<Chatter>)Session["ChatHistory"];
ChatRepository chatRepository = new ChatRepository();
List<Chatter> c = (List<Chatter>)chatRepository.getData();
//havent tested below
foreach (Chatter e in c)
{
var temp_lc = lc.Find(n => n.Name == e.Name);// Can we avoid linq?
if (temp_lc == null)
{
lc.Add(e);
}
else
{
// How to Addrange to Msgs?
}
}
var serializer = new JavaScriptSerializer();
var t = serializer.Serialize(lc);
return t;
}
非常感谢你!
答案 0 :(得分:1)
考虑使用chatters
和chatterHistory
等变量名称,而不是c
和lc
。它使阅读更容易。
尝试重写foreach
中的receiveMessages()
,如下所示:
foreach (Chatter e in c)
{
var temp_lc = lc.Where(x => x.Name == e.Name).SingleOrDefault();
if (temp_lc == null)
{
lc.Add(e);
}
else
{
temp_lc.Msgs = temp_lc.Msgs.Concat(e.Msgs).ToList();
}
}
如果temp_lc
存在,temp_lc.Msgs.Concat(e.Msgs).ToList()
会将Msgs
属性与e.Msgs
连接起来。 ToList()
将其转换为List<ChatMsg>
,然后我们可以将整个内容分配回temp_lc.Msgs
。
最后一步非常重要,因为Concat()
不会改变(更改)它所调用的对象 - 而是返回一个新对象,然后我们可以将其赋给{{ 1}}。