我有以下代码,将具有随机生成的值“ hawb”的实体作为列之一插入。我的想法是,由于 hawb 是表中的 unique 列,因此,在插入重复值时,try-catch块将捕获异常。在我开始对其进行测试并出现一些奇怪的错误之前,工作流工作正常。
[Code]
hawb = "0402135505536";
while (!uniqueHawb) //insert new hawb
{
//hawb = $"{DateTime.Now:MMddHHmmss}{RandomHelper.GetRandomNumber(0, 999):000}";
var entity = new HawbAsset { HAWB = hawb, HawbStatus = "Allocated", AllocatedDateTime = DateTime.Now, AllocationReference = reference };
try
{
_repository.Insert(entity);
uniqueHawb = true;
}
catch (Exception e)
{
;
}
hawb = $"{DateTime.Now:MMddHHmmss}{RandomHelper.GetRandomNumber(0, 999):000}";
}
[Model]
public class HawbAsset : BaseEntity
{
[Required(AllowEmptyStrings = false)]
[Index(IsUnique = true)]
[StringLength(15)]
public string HAWB { get; set; }
[Required(AllowEmptyStrings = false)]
public string HawbStatus { get; set; }
public DateTime? AllocatedDateTime { get; set; }
[Required(AllowEmptyStrings = false)]
public string AllocationReference { get; set; }
public DateTime? ConfirmedUsageDateTime { get; set; }
public DateTime? RecycledDateTime { get; set; }
public string Owner { get; set; }
}
我已经对重复值0402135505536进行了硬编码,因此它会在第一次出现时捕获“重复键异常”。但是,当hawb是随机生成的,并且我确定值不同时,它仍然捕获相同的“ Duplicate Key Exception”。谁能告诉我发生了什么事以及如何实现我的目标?谢谢!
答案 0 :(得分:3)
您看到的问题是因为您尝试插入一个具有重复ID的实体,但该实体失败了。重试时,您正在创建第二个实体并尝试插入该实体。第一个实体仍与上下文关联,并且仍将尝试保存。您需要先将其与上下文分离,然后再保存新替换或更新现有实体。 (如下)
hawb = "0402135505536";
var entity = new HawbAsset { HAWB = hawb, HawbStatus = "Allocated", AllocatedDateTime = DateTime.Now, AllocationReference = reference };
while (!uniqueHawb) //insert new hawb
{
//hawb = $"{DateTime.Now:MMddHHmmss}{RandomHelper.GetRandomNumber(0, 999):000}";
try
{
_repository.Insert(entity);
uniqueHawb = true;
}
catch (Exception e)
{
;
}
entity.HAWB = $"{DateTime.Now:MMddHHmmss}{RandomHelper.GetRandomNumber(0, 999):000}";
}
要分离实体,您需要使用context.Entity(entity).State = EntityState.Detached;
,它需要在存储库边界内进行操作。
虽然理想情况下,最好在尝试插入之前检查HAWB的唯一性,但对于在非常罕见的情况下,在检查和保存之间保存条目的情况,仍然可以处理异常:
int retryCount = 0
while (retryCount < 5)
{
try
{
bool isUnique = false;
string hawb = null;
while(!isUnique)
{
hawb = generateHawb();
isUnique = context.HawbAssets.Any(x => x.HAWB == hawb);
}
entity.HAWB = hawb; // this hawb should be unique, so set and insert.
_repository.Insert(entity);
}
catch(UpdateException)
{
// log that this has happened, check inner exception for duplicate key and retry, though limit retry attempts if there are deeper issues that might lock up the system in a retry loop.
retryCount++;
}
}
答案 1 :(得分:1)
其1行额外的代码来检查实体是否存在。首先,不要依靠错误处理来完成工作:
if ( _repository.HAWBAssets.FirstOrDefault(i => i.HAWB == hawb)== null)
{
_repository.Insert(entity);
uniqueHawb = true;
}
答案 2 :(得分:1)
也许您可以使用纳秒级的距离来缩短记录之间的距离,以减少重复的可能性
entity.HAWB = $"{DateTime.Now.Ticks}";
// 636898603227146583
DateTime.Ticks
分辨率为100纳秒