2017-04-03 91 views
0

我正在用C#Winforms創建一個簡單的消息應用程序。我正在連接到在我的電腦上運行的SQLEXPRESS服務器並將所有內容存儲在那裏。實體框架中的迭代錯誤

這裏是我的架構:

public class UserContext : DbContext { 
    public UserContext() : base("name=BuddyDatabase") { 

    } 
    public DbSet<User> Users { get; set; } 
    public DbSet<Message> Messages { get; set; } 
} 

public class User { 
    [Key] 
    public string username { get; set; } 
    public string password { get; set; } 

    public static implicit operator User(bool v) { 
     throw new NotImplementedException(); 
    } 

    public virtual List<User> friends { get; set; } 
} 

public class Message { 
    [Key] 
    public int ID { get; set; } 

    public virtual User sender { get; set; } 
    public virtual User recipient { get; set; } 

    public string content { get; set; } 

    public virtual List<User> group { get; set; } 
} 

很簡單

將消息發送到一個收件人的作品,但羣發不,每當我打開「信息屏」我得到這個錯誤:

無法創建類型爲'WindowsFormsApp1.User'的常量值。只有原始類型或枚舉類型在此上下文中受支持。

這是我所運行的方法,當消息屏幕負荷高達:

var x = db.Messages.Where(b => b.recipient.username == currentuser.username); 
foreach (var y in x) { 
    MainMessagesBox.Text += y.content; 
} 
x = null; 

var z = db.Messages.Where(b => b.group.Contains(currentuser)); 
foreach (var y in z) { 
    MainMessagesBox.Text += y.content; 
} 

(Visual Studio中突出了「中」在這一行的錯誤的原因。)

的foreach (var y in z){

認爲這可能是我使用Where方法時遇到的一個問題,涉及非基元(如錯誤消息所示),所以我嘗試更改我的模式,以便該組是一個字符串列表包含預期收件人的用戶名和修改相應的方法,但也沒有工作。根據要求將提供該試驗的代碼和錯誤。

下面是實際的「發送消息」的代碼:

if (!textBox1.Text.Contains(',')) { 
    db.Messages.Add(new Message { sender = currentuser, recipient = db.Users.Find(textBox1.Text), content = currentuser.username + ": " + ContentBox.Text + "\n" }); 
    db.SaveChanges(); 
} else { 
    List<User> recips = new List<User>(); 
    string[] poop = textBox1.Text.Split(','); 

    foreach (var x in poop) { 
     recips.Add(db.Users.Find(x)); 
    } 

    db.Messages.Add(new Message { sender = currentuser, group = recips, content = ContentBox.Text }); 
    db.SaveChanges(); 
} 

船尾是從一個文本框由逗號分隔,這是臨時的目標收件人的陣列。

對不起,如果有任何錯誤格式或我不清楚,這是我的第一個問題。

預先感謝您。

+0

您應該在Messages表中定義「發件人」和「收件人」的外鍵 - ref https://msdn.microsoft.com/en-us/library/jj713564(v=vs.113).aspx – Bitmask

+0

如果我理解正確,則會將消息發送給單個收件人或組。但是你不應該在數據庫中以不同的方式對待它。一條消息在收件人列表中有多個收件人,或者它只有一個。 – sbecker

回答

1

問題是您在檢查當前用戶是否在group列表中的消息表上的Select查詢。這不起作用,因爲查詢必須被轉換爲SQL才能發送到數據庫。

SQL不理解「用戶」類型是什麼,也無法比較引用。實際上,C#也沒有正確比較這一點。與您的情況相同的兩個「用戶」對象username不會相同。您需要比較這些對象的用戶名。

無論如何,正如Bitmask在註釋中解釋的那樣,您必須正確定義消息的外鍵。

這對消息的發送者來說很容易。您的User課程中有public virtual ICollection<Message> Messages { get; set; }

但是對於收件人來說,這是一個多對多的關係。因此,User類和Message類分別具有MessageUser的集合。

像這樣的東西應該工作:

public class User { 
    [Key] 
    public string username { get; set; } 
    public string password { get; set; } 

    public static implicit operator User(bool v) { 
     throw new NotImplementedException(); 
    } 

    public virtual ICollection<Message> SentMessages { get; set; } 
    public virtual ICollection<Message> ReceivedMessages { get; set; } 

    public virtual List<User> friends { get; set; } 
} 

public class Message { 
    [Key] 
    public int ID { get; set; } 

    public virtual User Sender { get; set; } 
    public virtual ICollection<User> Recipients { get; set; } 

    public string content { get; set; } 
} 

檢查this link關於如何定義一個例子的許多一對多使用數據註釋或流暢API關係無論是。這假定你使用EF6。如果您使用的是較早版本的EF,則可能需要自己定義連接表以獲取多對多關係。

至於查詢。您可以在消息屏幕中使用以下OnLoad方法:

MainMessagesBox.Text = string.Join(System.Environment.NewLine, currentuser.ReceivedMessages.Select(m => m.content)) 

這將連接所有消息,並用新行分隔。

+0

我實現了你給我的模式,我正在試圖平滑一切,但我無法刪除任何一個表中的任何行。我得到外鍵約束錯誤試圖刪除任何東西。這可能是一個noob錯誤,但請幫助。 – BaronessLover