EntityCommandExecutionException - 尝试链接1个数据库中的2个模型

时间:2016-12-16 19:09:45

标签: c# asp.net asp.net-mvc model-view-controller

我差不多有两个模型 - 一个公告,其中一些可以发布公告和一个看到的模型,确定是否有人看到了公告。她的模特儿是:

公布

public class Announcement
{
    public int AnnouncementId { get; set; }
    public string AnnouncementContent { get; set; }
    public virtual ApplicationUser User { get; set; }
}

和见过:

public class Seen
{
    public int SeenId { get; set; }

    public virtual Announcement Announcement { get; set; }
    public virtual ApplicationUser User { get; set; }
}

在我的AnnouncementController.Index我有这个代码几乎应该是,如果你查看这个页面,标记每个公告,因为看到但是在#34;新见的"部分:

public ActionResult Index()
{
    string currentUserId = User.Identity.GetUserId();
    var currentUser = db.Users.FirstOrDefault(x => x.Id == currentUserId);


    if(db.Announcements != null)
    {
        foreach (Announcement anoun in db.Announcements)
        {
            new Seen
            {
                User = db.Users.Add(currentUser),
                Announcement = db.Announcements.FirstOrDefault(x => x.AnnouncementId == anoun.AnnouncementId),
            };
        }
    }
    return View(db.Announcements.ToList());
}
  

已经有一个与此命令关联的打开DataReader,必须先关闭它。

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
    {
        public ApplicationDbContext()
            : base("DefaultConnection", throwIfV1Schema: false)
        {
        }

        public DbSet<Announcement> Announcements { get; set; }
        public DbSet<Comment> Comments { get; set; }
        public DbSet<Seen> Seens { get; set; }

        public static ApplicationDbContext Create()
        {
            return new ApplicationDbContext();
        }
    }

2 个答案:

答案 0 :(得分:0)

错误是因为您正在主动迭代来自数据库的集合流,然后尝试将另一个select重新发布到该循环内的数据库。可以通过在使用ToList()进入循环之前强制实现集合的实现来修复它(其他选项也可用,如AsEnumerableToArray)。

foreach (Announcement anoun in db.Announcements.ToList())
{
    new Seen
    {
        User = db.Users.Add(currentUser),
        Announcement = db.Announcements.FirstOrDefault(x => x.AnnouncementId == anoun.AnnouncementId),
    };
}

话虽如此,我不确定你为什么这样做。为什么不直接附加实例anoun,因为您只使用单个(或显示的代码中相同)DbContext实例(名为db的变量)。

foreach (Announcement anoun in db.Announcements)
{
    new Seen
    {
        User = currentUser, // also this seemed wrong before, just assign the reference directly
        Announcement = anoun
    };
}

或者说它更简单:

var newSeens = db.Announcements.Select(x => new Seen(){User = currentUser, Announcement = x}).ToList();
db.Seens.AddRange(newSeens);
db.SaveChanges();

这假设用户没有看到任何通知。如果用户看过一些,那么您需要在该用户的现有db.Announcements记录上过滤Seen

答案 1 :(得分:0)

如果您没有出现该错误,则仍有其他问题。见下文:

public ActionResult Index() {
string currentUserId = User.Identity.GetUserId();
var currentUser = db.Users.FirstOrDefault( x => x.Id == currentUserId );

List<Seen> seens = new List<Seen>();
if( db.Announcements != null ) {
   foreach( Announcement anoun in db.Announcements ) {
      seens.Add(
      new Seen
      {
         User = currentUser, // You have this already so why go to the database again?
         Announcement = anoun, // Same with this.
      });

   }
}

// Save seens to the database

return View( db.Announcements.ToList() );