实体框架中的迭代错误

时间:2017-04-03 01:35:42

标签: c# sql .net winforms entity-framework

我正在使用C#Winforms创建一个简单的Messaging应用程序。我正在连接到在我的计算机上运行的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; }
}

很简单

每当我打开“消息屏幕”时,向单个收件人发送消息都有效但组消息不会发生。我收到这个错误:

无法创建类型&#39; WindowsFormsApp1.User&#39;的常量值。在此上下文中仅支持原始类型或枚举类型。

这是我在消息屏幕加载时运行的方法:

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突出显示此行中的&#39; in&#39;作为错误原因。)

foreach(z中的var y){

认为这可能是我使用Where方法并涉及非基元的问题(如错误消息所示)所以我尝试更改我的架构,以便该组是包含预期收件人的用户名的字符串列表相应地修改了方法但是也没有用。将根据请求为该试验提供代码和错误。

这是实际的&#34;发送消息&#34;代码:

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();
}

poop是一个由逗号从文本框中分隔的目标收件人数组,这是暂时的。

对不起,如果有任何错误格式或我不清楚,这是我的第一个问题。

提前谢谢。

1 个答案:

答案 0 :(得分:1)

问题是选择查询消息表,您在其中检查当前用户是否在group列表中。这不起作用,因为必须将查询转换为SQL才能发送到数据库。

SQL不了解'用户'类型是什么,无法比较引用。实际上,C#也没有比较正确。在您的情况下,具有相同username的两个“用户”类型的对象将不相同。您需要比较这些对象的用户名。

无论如何,正如Bitmask在评论中所解释的那样,您必须正确定义消息的外键。

邮件的发件人很容易。您的public virtual ICollection<Message> Messages { get; set; }课程中有User

但是对于收件人来说,这是一种多对多的关系。因此,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))

这会连接所有消息,用新行分隔。

相关问题