c# - 如何在 Entity Framework 5 中表达 "has many through"关系?

标签 c# mysql entity-framework entity-framework-5

我正在尝试使用 Entity Framework 5 查询现有的 MySQL 数据库。我使用代码优先创建了一个基于代码的模型,该模型映射到 this tutorial on MSDN 之后的现有数据库。 .

我有两个表:usersbuddiesUser 有一个 id、一个 name 和一个 emailBuddy 有一个 user_id 和一个 buddy_id。一个 User 有很多 Buddies(它们也是 Users)。 buddy_id 列是返回 Users 表的外键。所以每个 User 通过 Buddies 有很多 User

public class User
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
    public IList<User> Buddies { get; set; } 
}

这是我的数据库访问代码:

using (var db = new Models.fooContext())
{
    foreach (Models.user user in db.users)
    {
        var u = new User
        {
            Id      = user.id,
            Name    = user.name,
            Email   = user.email,
            Buddies = new List<User>()
        };

        // this is obviously very inefficient but I am just
        // trying to get anything to work
        foreach (Models.buddy buddy in db.buddies) // this line throws an exception
        {
            if (buddy.user_id == user.id)
            {
                var b = new User();
                // take buddy.user_id and find this user in the user table
                u.Buddies.Add(b);
            }
        }

        // serialize User and write it to a file here
    }
}

此代码在上面指示的行中抛出以下异常:

System.Data.EntityCommandExecutionException: an error occurred while executing the command definition. See the inner exception for details."

内部异常是一个带有消息的MySql.Data.MySqlClient.MySqlException

There is already an open DataReader associated with this Connection which must be closed first.

我的问题:

  1. 如何创建一种关系,告诉 EF 每个 User 都有很多 Buddies
  2. 一旦 EF 知道一个 User 有很多 Buddies,我该如何使用 buddy_id 找到 User 为那个 Buddy 录音?

最佳答案

您有一种数据类型,您正在调用不同的名称。这有点令人困惑。但是,要首先使用代码使其工作,您只需要在自定义 DbContext 类中进行以下流畅的配置:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<user>().
      HasMany(c => c.Buddies).
      WithMany().
      Map(
       m =>
       {
          m.MapLeftKey("user_id");
          m.MapRightKey("buddy_id");
          m.ToTable("buddies");
       });
}

假设您的用户类如下所示:

[Table("user")]
public class user
{
    public int id { get; set; }
    public string name { get; set; }
    public string email { get; set; }
    public virtual List<user> Buddies { get; set; }
}

如果您使用上述方法,您拥有的每个用户对象都会有一个名为 Buddies 的导航属性。查询用户时,您将希望急切加载好友用户,请执行以下操作:

context.users.Include("Buddies")

此外,与多个读者一起解决您的问题。这是因为您没有从第一个循环中枚举查询 (db.users)。要解决这个问题,您可以像这样枚举查询:

var users = context.users.Include("Buddies").ToList();
foreach(var user in users)....

如果您使用上面的配置,您不需要尝试匹配 id,您只需使用好友导航属性(虚拟,延迟加载),做:

user.Buddies

如您所见,您实际上并不需要“Model.buddy”(因为它只包含一个 id 映射) Entity Framework 将负责链接。但是,如果您并不总是在用户查询中包含 Buddies,您可能需要该表。将通过以下方式使用 LINQ 查询:

var userBuddies = db.buddies.Where(buddy=>buddy.user_id == user.id).ToList();
//An enumerated list of user buddies 
//do stuff

关于c# - 如何在 Entity Framework 5 中表达 "has many through"关系?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19550923/

相关文章:

c# - Linq2Sql : How to handle tables with the same name and different schema names

c# - 在 MonthCalendar 中选择特定日期时如何删除项目

php - Laravel 查询数据库 'AND' 'OR' Where or Where

entity-framework - Entity Framework 和带有自定义实体的存储过程

c# - 直接修改 List<T> 元素

c# - 在.NET Framework中创建JSONObject的库

php - 向复杂的 SQL select 语句添加字段

c# - 如果我在不同时间使用同一 Linq 查询的不同字段, Entity Framework 是否会多次查询数据库?

c# - MVC ViewModel EntityFrameWork ICollection,IEnumerable 虚拟类

c# - 使用 Magick.NET 生成带标题的图像