我在将单体 ASP.NET MVC 应用程序拆分为 N 层应用程序时遇到了很大的困难。在以下示例中,在第一次调用_messageRepo.Create()期间,会引发异常,表明DbContext无法使用,因为它已被释放。
我看不到这是如何发生的,并且尝试中断Dispose()方法实际上并不会导致应用程序在调试期间中断。
基本结构如下:
这些实例会在需要时重建,如下例所示
using(var context = new MyContext())
{
_messageRepo = new MessageRepository(context);
_idRepo = new IdentityRepository(context);
var status = _messageRepo.GetStatus(Int32.Parse(message.To));
message.To = status.Header.From.Name;
message.ToHash = Obfuscate.SaltAndHash(message.To);
message.Subject = "RE:" + status.Header.Subject;
var toUser = _idRepo.Get(message.To);
var fromUser = _idRepo.Get(_userName);
var rawMessage = new Message()
{
Content = message.Content,
Attachments = GetAttachments(message.AttachmentIds)
};
var header = …Run Code Online (Sandbox Code Playgroud)在另一篇文章中,我要求澄清何时使用DbSet<TEntity>.Local. 我还没有得到答案,我认为这个问题可能包含太多信息。深入挖掘后,我可以提出一个更具体的问题。
希望你们能够解释在我的场景中选择两个选项中的哪一个。
我正在尝试从我的Repository. 这些实体仍处于“已添加”状态(即我尚未调用该SaveChanges方法)。我需要这个,因为我想将实体存储在一个原子操作中,所以我必须推迟调用,SaveChanges直到验证完整的模型之后。
此外,我需要符合 IQueryable 接口,因为我有使用扩展方法来延迟加载导航属性的依赖Include代码Queryable。
过去几天发生了很多事情,但归结为以下两种不同的方法:
DbSet<TEntity>.Local通过属性DbContext.ChangeTracker public void AddAndRetrieveUncommittedEntityFromDbContext()
{
Database.SetInitializer(new DropCreateDatabaseAlways<TestContext>());
var testContext = new TestContext();
// Initialize the entities and store them in the repository
var tenant = new Tenant { Name = "test", Guid = Guid.NewGuid().ToString() };
var user = new User { Name = "bas", EmailAddress = "bas@domain.com", Password = …Run Code Online (Sandbox Code Playgroud) 有没有办法在不实际连接到数据库的情况下创建 DbContext?
我希望能够访问 CSDL 和 SSDL 元数据,如下所示:
var objContext = ((IObjectContextAdapter)myDbContext).ObjectContext;
var ssdl = objContext.MetadataWorkspace.GetItemCollection(DataSpace.SSpace);
var csdl = objContext.MetadataWorkspace.GetItemCollection(DataSpace.CSpace);
Run Code Online (Sandbox Code Playgroud)
但我根本不想访问数据库。理想情况下,我希望能够在没有数据库的情况下访问 SSDL/CSDL 元数据。
在我的控制器的单元测试中,我模拟了数据库上下文类,将一个假数据库上下文对象注入到控制器构造函数中。假上下文类具有假 DBSet 类,并且它们工作正常。但是,我不知道如何伪造 POST 单元测试的 DbEntityEntry.Entry() 方法。简化的POST方法代码如下
[ResponseType(typeof(Trip))]
public async Task<IHttpActionResult> PostTrip(Trip trip)
{
db.Trips.Add(trip);
await db.SaveChangesAsync();
//Load driver user object
db.Entry(trip).Reference(x => x.User).Load();
var tripDTO = new TripDTO()
{
Id = trip.Id,
Status = trip.Status,
BookedSeats = trip.BookedSeats,
DriverName = trip.User.Name,
};
return CreatedAtRoute("DefaultApi", new { id = trip.Id }, tripDTO);
}
Run Code Online (Sandbox Code Playgroud)
显然,我必须以某种方式模拟 DbEntityEntry.Entry() 方法,以使 db.Entry(trip).Reference() 方法能够与 LINQ 表达式一起使用。如果您以前遇到过类似的问题,可以帮忙吗?
多谢。
首先,如果这个问题已经得到回答,我很抱歉。但我无法找到解决方案。
假设我想创建一个订单以及一些行,同时创建另一个实体。
服务层:
public class OrderService
{
private DbContext context;
public OrderService()
{
context = new DbContext();
}
public void AddOrder(Order order, List<Orderline> lines, AnotherEntity anotherEntity)
{
context.Orders.Add(order);
context.Orderlines.AddRange(lines);
var anotherService = new AnotherService();
anotherService.AddAnother(anotherEntity)
context.SaveChanges();
}
}
public class AnotherService
{
private DbContext context;
public AnotherService()
{
context = new DbContext();
}
public void AddAnother(AnotherEntity entity)
{
// Maybe some business rules here
context.SomeOtherEntities.Add(entity);
context.SaveChanges();
}
}
Run Code Online (Sandbox Code Playgroud)
控制器:
var orderService = new OrderService();
orderService.Add(order, lines, anotherEntity);
Run Code Online (Sandbox Code Playgroud)
第一个问题是我在两个服务中有不同的上下文,因此有两个不同的事务。我能想到的解决方案:
将 dbcontext …
.net entity-framework transactionscope unit-of-work dbcontext
我的 EF Core 实体:
public class Order {
public string Code { get; set; }
public ICollection<LineItem> LineItems { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我可以使用以下方法获取该属性的原始值Code:
context.Entry(myOrder).OriginalValues["Code"]
Run Code Online (Sandbox Code Playgroud)
但如果我尝试对LineItems导航集合属性进行此操作,则会抛出以下错误:
The property LineItems on entity type Order is being accessed using the 'Property' method, but is defined in the model as a navigation property. Use either the 'Reference' or 'Collection' method to access navigation properties.
该异常消息并不涉及我可以找到的方法。
那么如何获取导航集合属性的原始值呢?
这个问题不是关于 c# 一般的“使用”,而不是关于何时/为什么使用它等等。
问题是,DBContext 对象是否自己处理连接,因此我不需要使用using它来处理它,没有关于它的问题,所以不要将其标记为重复
using (DBContext db = new DBContext())
{
var Order = db.Order.First(r => r.OrderID == 6);
Order.Type = 6;
db.SaveChanges();
}
Run Code Online (Sandbox Code Playgroud)
或者不使用
DBContext db = new DBContext();
var Order = db.Order.First(r => r.OrderID == 6);
Order.Type = 6;
db.SaveChanges();
Run Code Online (Sandbox Code Playgroud)
因为我在这个来源中看到using没有必要,最好不要使用它。
实体框架会为我处理连接吗?
我正在编写我的第一个 ASP.NET Core Web API,并试图找出如何将我的 DbContext 对象注入到我的存储库构造函数中。我遵循了本教程的 EF 部分,其中 DbContext 通过注册到服务集合services.AddDbContext<DbContext>并services.GetRequiredService<DbContext>()用于初始化数据库值。
public class Startup
{
public IConfiguration Configuration {
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddSingleton<IItemRepository, ItemRepository>();
services.AddSingleton<IUserRepository, UserRepository>();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new Info { Title = "My API", Version = "v1" });
});
services.AddDbContext<RAFYCContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
}
}
Run Code Online (Sandbox Code Playgroud)
public class Program
{
public static void Main(string[] args)
{
//CreateWebHostBuilder(args).Build().Run();
IWebHost host = CreateWebHostBuilder(args).Build();
using (IServiceScope scope = host.Services.CreateScope())
{
IServiceProvider services = …Run Code Online (Sandbox Code Playgroud) 我在我的项目中应用了 ASP.NET Core 3.1,我想通过代码优先的方法创建数据库并使用 MySQL。在 startup.cs 文件中,我收到此错误:
CS1061“MySQLDbContextOptionsBuilder”不包含“ServerVersion”的定义,并且没有可访问的扩展方法“ServerVersion”接受“MySQLDbContextOptionsBuilder”类型的第一个参数
我该如何解决?
在startup.cs中:
using Microsoft.EntityFrameworkCore;
using Pomelo.EntityFrameworkCore.MySql.Infrastructure;
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContextPool<Alpha.Web.App.ApplicationDbContext>(options =>
options.UseMySQL(Configuration["ConnectionStrings:DefaultConnection"],
mysqlOptions =>
{
mysqlOptions.ServerVersion(new Version(8, 0, 20), ServerType.MySql);
}));
}
Run Code Online (Sandbox Code Playgroud) dbcontext entity-framework-core asp.net-core asp.net-core-3.0
System.InvalidOperationException: '数据库提供程序试图注册'IRelationalTypeMappingSource' 服务的实现。这不是实体框架定义的服务,因此必须使用“TryAddProviderSpecificServices”方法注册为特定于提供者的服务。
这是我在 DbContext 中运行页面时的例外情况。
该网站是 Razor Pages。
网站运行良好,我没有改变任何东西,现在发生了。
这是 .csproj
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="1.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.10" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.10">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="3.1.4" />
<PackageReference Include="Microsoft.Windows.Compatibility" Version="5.0.0" />
</ItemGroup>
</Project>
Run Code Online (Sandbox Code Playgroud)
有谁知道如何解决这个问题?
dbcontext ×10
c# ×8
.net ×2
asp.net-core ×2
repository ×2
dispose ×1
mocking ×1
razor-pages ×1
unit-of-work ×1
unit-testing ×1