C# EntityCommandExecutionException-尝试链接1个数据库中的2个模型
我有两个模型——一个是公告,有些人可以发布公告,另一个是SEED模型,用于确定是否有人看过公告。她的eis是模型: 宣布:C# EntityCommandExecutionException-尝试链接1个数据库中的2个模型,c#,asp.net,asp.net-mvc,model-view-controller,C#,Asp.net,Asp.net Mvc,Model View Controller,我有两个模型——一个是公告,有些人可以发布公告,另一个是SEED模型,用于确定是否有人看过公告。她的eis是模型: 宣布: public class Announcement { public int AnnouncementId { get; set; } public string AnnouncementContent { get; set; } public virtual ApplicationUser User { get; set; } } 我们看到: p
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中,我有一段代码,这段代码应该是,如果您查看此页面,请将每个公告标记为已看到,但我在“新看到”部分遇到错误:
已存在与此命令关联的打开的DataReader,必须先关闭该命令
public类ApplicationDbContext:IdentityDbContext
{
公共应用程序上下文()
:base(“DefaultConnection”,throwifvv1schema:false)
{
}
公共数据库集公告{get;set;}
公共DbSet注释{get;set;}
公共数据库集seen{get;set;}
公共静态应用程序上下文创建()
{
返回新的ApplicationDbContext();
}
}
该错误是因为您正在对来自数据库的集合流进行主动迭代,然后试图在该循环中向数据库重新发出另一个select。可以通过在进入循环之前使用ToList()
(其他选项也可用,如AsEnumerable
或ToArray
)强制实现集合的物化来修复此问题
尽管如此,我不知道你为什么这样做。为什么不直接附加实例anoun
,因为您只使用一个实例(或所示代码中的同一个实例)DbContext
实例(变量名为db
)
或者让它变得更简单:
var newSeens = db.Announcements.Select(x => new Seen(){User = currentUser, Announcement = x}).ToList();
db.Seens.AddRange(newSeens);
db.SaveChanges();
这假设用户没有看到任何公告。如果用户看到了一些,那么您需要过滤该用户现有的
seed
记录上的db.Announcements
。事件如果没有该错误,您仍然存在其他问题。见下文:
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() );
public ActionResult Index(){
字符串currentUserId=User.Identity.GetUserId();
var currentUser=db.Users.FirstOrDefault(x=>x.Id==currentUserId);
列表seens=新列表();
if(db.Announcements!=null){
foreach(数据库公告中的另一个公告){
seens.添加(
新秀
{
User=currentUser,//您已经有了它,为什么还要再次转到数据库?
Announcement=anoun,//与此相同。
});
}
}
//将seen保存到数据库
返回视图(db.Announcements.ToList());
当您遇到错误并询问有关该错误的问题时,您需要将该错误包括在内。在这种情况下,该错误称为an(这就是错误在.net中的表现方式)。包括消息、类型、堆栈跟踪,并在InnerExceptions中递归重复此操作。请使用问题的编辑链接包含此详细信息,不要将其作为注释。请阅读。谢谢!底部的一个不起作用,但这不是我要找的,因此无论如何,谢谢你。新问题EM是我没有任何错误与第二种方法,但没有记录添加到SENS数据库。@ Pigeon MykFoots -它是因为你没有添加到<代码> DbValue,也没有调用<代码> Dava.SaveCuxes();< /代码>之后。但是很高兴帮助。@鸽子MykFoots -也请考虑接受答案(参见)您好,谢谢您的回复。我添加了:db.Seens.AddRange(Seens);db.SaveChanges();但这仍然没有更新数据库,任何想法我都被难住了。你有错误吗?没有,这与我看到的模型有关,因为看到的数据库包含:SeenId、Announcement_AnnouncementId和User_id,这取决于SeenId是什么。我看不到你的dbcontext代码,所以很难说。但是的,很可能是因为这个。我只是edi把它和我的dbContext放在一起
foreach (Announcement anoun in db.Announcements.ToList())
{
new Seen
{
User = db.Users.Add(currentUser),
Announcement = db.Announcements.FirstOrDefault(x => x.AnnouncementId == anoun.AnnouncementId),
};
}
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();
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() );