其他分享
首页 > 其他分享> > 我如何在Entity Framework 5中表达“有很多通过”关系?

我如何在Entity Framework 5中表达“有很多通过”关系?

作者:互联网

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

我有两个表:用户和伙伴.用户具有ID,名称和电子邮件.好友有一个user_id和一个buddy_id.一个用户有很多好友(也是用户). buddy_id列是回到用户表的外键.因此,每个用户通过伙伴都有许多用户.

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.

我的问题:

>如何创建一个关系来告诉EF每个用户都有很多好友?
> EF知道用户有很多好友后,如何使用buddy_id查找该好友的用户记录?

解决方法:

您有一种要调用单独名称的数据类型.这有点令人困惑.但是,要使其首先与代码一起使用,您只需在Custom 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映射)
实体框架将负责链接.但是,如果您并不总是在用户查询中包括伙伴,则可能需要该表.可以使用LINQ通过以下方式查询:

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

标签:mysql,entity-framework,entity-framework-5,c-2
来源: https://codeday.me/bug/20191011/1895253.html