Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 当SaveChanges()失败时,如何管理.NET Core中db上下文的作用域_C#_Asp.net Core_.net Core_Entity Framework Core - Fatal编程技术网

C# 当SaveChanges()失败时,如何管理.NET Core中db上下文的作用域

C# 当SaveChanges()失败时,如何管理.NET Core中db上下文的作用域,c#,asp.net-core,.net-core,entity-framework-core,C#,Asp.net Core,.net Core,Entity Framework Core,我们有一个由Azure服务总线队列触发的.NET核心控制台应用程序。我的理解是,通过DI的DbContext的默认生存期是限定范围的,建议让DI和框架管理生存期,而不是使用使用语句。但是,在下面的情况下,我们调用SaveChanges(),它失败了,因此我们尝试再次调用它以向数据库写入日志。这里推荐的方法是什么?当DI将上下文注入调用类时,使用和感觉很奇怪 try { db.Add(new MyEntity()); db.SaveChanges(); } catch (Excep

我们有一个由Azure服务总线队列触发的.NET核心控制台应用程序。我的理解是,通过DI的DbContext的默认生存期是
限定范围的
,建议让DI和框架管理生存期,而不是使用
使用
语句。但是,在下面的情况下,我们调用
SaveChanges()
,它失败了,因此我们尝试再次调用它以向数据库写入日志。这里推荐的方法是什么?当DI将上下文注入调用类时,使用
感觉很奇怪

try
{
    db.Add(new MyEntity());
    db.SaveChanges();
}
catch (Exception ex) // a constraint is violated
{
    db.Add(new LogEntity("Unable to save MyEntity"));
    db.SaveChanges(); // this fails because MyEntity is still in scope of the context
}
我的理解是,DbContext的默认生存期是通过DI实现的 是有范围的,建议让DI和框架管理 使用
语句而不是使用
语句的生存期

这并不准确,DI是一种实例化对象的方法,但您仍然可以控制对象的范围。。。使用Ninject()的示例:

//这将在每个请求上创建一个新的MyType实例
kernel.Bind().To().InTransientScope();
//这将在同一线程中共享MyType实例
kernel.Bind().To().InThreadScope();
//这将在同一Web请求中共享MyType实例
kernel.Bind().To().InRequestScope();

关于DbContext的范围,请参见:

DataContext是轻量级的,创建起来并不昂贵。典型的 LINQ to SQL应用程序在方法范围内创建DataContext实例 或者作为短期类的成员,这些类表示 相关数据库操作

因此,通常最好在同一方法中共享
DbContext
的同一实例这里的例外是日志记录。将记录器的
DbContext
与其正在记录的操作混合使用不是一个好主意。日志应该独立于这些操作。。。您可以选择将您的消息记录在文本文件、电子邮件、数据库。。。如果要使用DB进行日志记录,可以考虑为日志消息使用不同的DB。还考虑使用日志记录框架,如ETC < /P> <代码> // /最安全的方式之一,因为DbContext不是线程安全的。 清单项目; 等待使用(var_dataContext=newdatacontext(connectionString:“连接字符串”)) { Boughts=wait_dataContext.YourModel.toListSync(); }
你是正确的-如果
数据库被注入,你不应该
处置
(即不需要
使用
)。这是集装箱的工作。我谦恭地不同意下面的答案(就
使用
而言)。在日志方面,我建议使用日志库写入日志,而不是使用db上下文。如果可能的话,您可以将实体状态设置为已分离,然后保存日志?与db.Entry(myEntity).State=EntityState.DetachedIt类似,建议使用不同的
DbContext
拆分业务逻辑和日志逻辑。我建议您为不同的选项注入两个DbContext。或者,您可以考虑为日志记录创建一个新服务,它将将代码< > dBaseX注入其中。然后,在需要时使用此日志服务。您的链接是关于
Linq.DataContext
,而不是
DbContext
。不管怎样,谢谢你的意见。我们正在考虑将DbContext生存期设置为Transient,或者寻找一种分离日志服务的方法。
// this would create a new MyType instance on every request
kernel.Bind<IMyType>().To<MyType>().InTransientScope();

// this would share MyType instance within the same Thread
kernel.Bind<IMyType>().To<MyType>().InThreadScope();

// this would share MyType instance within the same Web Request
kernel.Bind<IMyType>().To<MyType>().InRequestScope();
//// one of safest way as DbContext is not thread safe 
List<Model> Items;
await using (var _dataContext = new DataContext(connectionString:"connection String"))
{
    Boughts = await _dataContext.YourModel.ToListAsync();
}