第二次运行迁移时出错.似乎通用回购需要处理,我不知道如何处理



请耐心等待,我在这里真的很挣扎。

我对EF Core的依赖性注入还比较陌生。我来自旧的asp.net世界中的新类等,但我想尝试使用依赖注入。由于我们的旧数据库也需要迁移到新的结构中,我认为一个好的第一个应用程序应该是编写一个使用依赖注入的应用程序。我决定使用Blazor作为我们的最终代码库。

有两个数据库,一个叫QOnT,另一个叫iSele。我正在使用包括在内的多个网站将数据从QOnT迁移到iSelehttps://ngohungphuc.wordpress.com/2018/05/01/generic-repository-pattern-in-asp-net-core/和https://learn.microsoft.com/en-us/aspnet/mvc/overview/older-versions/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application-我创建了两个通用存储库。一个用于QOnT表,另一个将作为最终应用程序回购。我还为两者创建了一个通用的工作单元。

Generics和Tony的Tech&语言博客或https://ngohungphuc.wordpress.com/除了一个更改,它迎合了我需要插入和更新标识字段中的项目的事实。所以我创建了一个通用例程,它禁用身份检查,然后插入并重新打开。我把它粘贴在下面:

public T AddWithIDOn(T entity, string TableName)
{
_loggerManager.LogDebug($"FancyRepo -> AddWithIDOn {typeof(T)}, enttity {entity.ToString()}, Table: {TableName} ");
_context.Database.OpenConnection();
try
{
_context.Database.ExecuteSqlRaw($"SET IDENTITY_INSERT {TableName} ON");
_context.Set<T>().Add(entity);
_context.SaveChanges();
_context.Database.ExecuteSqlRaw($"SET IDENTITY_INSERT {TableName} OFF");
}
catch (Exception ex)
{
_loggerManager.LogInfo($"!!!Error!!! FancyRepo -> AddWithIDOn error: {ex.Message}");
}
finally
{
_context.Database.CloseConnection();
}
return entity;
}

这很好用。

在Startup.cs中,我添加了DbContexts和工作单元

public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
services.AddServerSideBlazor();
services.AddDbContextPool<ApplicationDbContext>(options =>
{
options.UseSqlServer(Configuration.GetConnectionString("iSeleConnection"));
options.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);
options.EnableSensitiveDataLogging(true);
});
services.AddDbContext<QOnTDbContext>(qontoptions =>
{
qontoptions.UseSqlServer(Configuration.GetConnectionString("QOnTConnection"));
});
//services.AddScoped(typeof(IQOnTGenericRepository<>), typeof(QOnTGenericRepository<>));
services.AddScoped(typeof(IQOnTUnitOfWork), typeof(QOnTUnitOfWork));
// services.AddScoped(typeof(IGenericRepository<>), typeof(IGenericRepository<>));
services.AddScoped(typeof(IUnitOfWork), typeof(UnitOfWork));
// logger
services.AddSingleton<ILoggerManager, LoggerManager>();
}

你会看到我已经评论掉了服务。转发的addscope是Unitofwork创建它们。

那么我有一个";代码隐藏";或者我为迁移客户的剃须刀后面的名字,它是CompnentBase

所以

public partial class MigrateCustomersBase : ComponentBase

在那里我注入了两个UnitOfWorks

[Inject]
private IQOnTUnitOfWork _QOnTUnitOfWork { get; set; }
[Inject]
private IUnitOfWork _iSeleUnitOfWork { get; set; }

我在表单上有一个按钮,点击它可以进行迁移:


IQOnTGenericRepository<CustomerTypeTbl> QOnTCustomerTypeTbl = _QOnTUnitOfWork.Repository<CustomerTypeTbl>();
ICollection<CustomerTypeTbl> QOnTCustomerTypes = QOnTCustomerTypeTbl.GetAll();
foreach (var srcCusType in QOnTCustomerTypes)
{
CustomerType tgtCusType = _iSeleUnitOfWork.Repository<CustomerType>().Find(ct => ct.CustomerTypeID == srcCusType.CustTypeId);
if (tgtCusType == null)
{
Logger.LogDebug($"  *Inserting CustomerType with id: {srcCusType.CustTypeId} and name {srcCusType.CustTypeDesc}");
_iSeleUnitOfWork.Repository<CustomerType>().AddWithIDOn(new CustomerType
{
CustomerTypeID = srcCusType.CustTypeId,
CustomerTypeName = srcCusType.CustTypeDesc,
HasExtendedOptions = false,
Notes= string.Format("Migrated from QOnT.CustomerTypeTbl {0:d}", DateTime.UtcNow.Date)                        
}
, "iSele.CustomerTypes");
}
else
{
tgtCusType.CustomerTypeName = srcCusType.CustTypeDesc;
tgtCusType.HasExtendedOptions = false;
tgtCusType.Notes = string.Format("Migrated from QOnT.CustomerTypeTbl {0:d}", DateTime.UtcNow.Date);
Logger.LogDebug($"  *Updating Area with id: {tgtCusType.CustomerTypeID} and name {tgtCusType.CustomerTypeName}");
_iSeleUnitOfWork.Repository<CustomerType>().Update(tgtCusType);
}
}
}

那么,在这一切之后,我的问题是什么呢。好吧,我第一次运行代码时,一切都很好。然而,如果我再次点击按钮(调用代码(,那么我会得到一个错误

无法跟踪实体类型"CustomerType"的实例,因为已在跟踪键值为"{CustomerTypeID:1}"的另一个实例。附加现有实体时,请确保仅附加一个具有给定键值的实体实例

对我来说,这看起来像是存在多个UnitOfWorks。如果我离开页面并返回,它会再次工作。这只是第二次点击按钮,但它不起作用。我做错了什么,我该如何处理UnitOfWork?我需要刷新页面吗?

所以我停止使用依赖注入,我修改了点击时调用的函数,如下所示:

var optionsBuilder = new DbContextOptionsBuilder<ApplicationDbContext>();
optionsBuilder.UseSqlServer(ConString);
optionsBuilder.EnableSensitiveDataLogging(true);
optionsBuilder.EnableDetailedErrors(true);
ApplicationDbContext _iSeleDbContext = new ApplicationDbContext(optionsBuilder.Options);
UnitOfWork _iSeleUnitOfWork = new UnitOfWork(_iSeleDbContext, Logger);
IQOnTFancyGenericRepository<CustomerTypeTbl> QOnTCustomerTypeTbl = _QOnTUnitOfWork.Repository<CustomerTypeTbl>();
ICollection<CustomerTypeTbl> QOnTCustomerTypes = QOnTCustomerTypeTbl.GetAll();
foreach (var srcCusType in QOnTCustomerTypes)
{
CustomerType tgtCusType = _iSeleUnitOfWork.Repository<CustomerType>().Find(ct => ct.CustomerTypeID == srcCusType.CustTypeId);
if (tgtCusType == null)
{
//await 
Logger.LogDebug($"  *Inserting CustomerType with id: {srcCusType.CustTypeId} and name {srcCusType.CustTypeDesc}");
_iSeleUnitOfWork.Repository<CustomerType>().AddWithIDOn(new CustomerType
{
CustomerTypeID = srcCusType.CustTypeId,
CustomerTypeName = srcCusType.CustTypeDesc,
HasExtendedOptions = false,
Notes = string.Format("Migrated from QOnT.CustomerTypeTbl {0:d}", DateTime.UtcNow.Date)
}
, "iSele.CustomerTypes");
}
else
{
tgtCusType.CustomerTypeName = srcCusType.CustTypeDesc;
tgtCusType.HasExtendedOptions = false;
tgtCusType.Notes = string.Format("Migrated from QOnT.CustomerTypeTbl {0:d}", DateTime.UtcNow.Date);
Logger.LogDebug($"  *Updating Area with id: {tgtCusType.CustomerTypeID} and name {tgtCusType.CustomerTypeName}");
_iSeleUnitOfWork.Repository<CustomerType>().Update(tgtCusType);
}
}
_iSeleUnitOfWork.Dispose();

所以我现在迷路了。依赖注入似乎很糟糕。但为什么互联网上的人都推荐它呢?这不是一个切实可行的解决方案。

相关内容

  • 没有找到相关文章

最新更新