目前,我正在寻找一个端点并将数据存储在以下实体框架核心类中:
using System;
using System.Collections.Generic;
using System.Text;
namespace [removed].[removed].DataAccess.Entities
{
public class ResourceRegistration
{
public Guid Id { get; set; }
public Guid? ResourceId { get; set; }
public string ExternalId { get; set; }
public Guid? RegistrationStatusId { get; set; }
public Guid? EventId { get; set; }
public Guid? CourseId { get; set; }
public Guid? ResourceDocumentId { get; set; }
public double? Score { get; set; }
public string Uri { get; set; }
public DateTime? CompletedOn { get; set; }
}
}
在某些时候,我们的DBA将ExternalId表示为一个Int值,这很可能是因为ExternalId是多态的,但是在我的特定情况下,它是Guid。作为一种折衷,他将数据库中的列从int
更改为nvarchar(64)
值。
现在,我遇到一个可疑的问题,当通过AWS .NET Mock Lambda测试工具调用SaveChangesAsync
方法时,我收到以下错误:
System.Data.SqlClient.SqlException:转换时转换失败 数据类型为int的nvarchar值“ [已删除guid]”。
令人怀疑的是,由于尝试将Guid转换为 old 数据类型而导致转换失败。
我已经确认该列在数据库中被表示为nvarchar(64)
。我还确认我的连接字符串指向正确的数据库。
正在使用的模拟方法:
private async Task UpsertRegistrations(Registration[] registrations, Guid documentTemplateId)
{
DbContextOptions registrationOptions = new DbContextOptionsBuilder()
.UseSqlServer(this.[variable for db])
.Options;
using (ArloContext db = new ArloContext(registrationOptions))
{
foreach (Registration registration in registrations)
{
ResourceRegistration resourceRegistration = db.ResourceRegistrations.SingleOrDefault(r => r.ExternalId == registration.UniqueIdentifier.ToString());
AbbreviatedResource contact = db.Resources.FromSql("SELECT Id, Email FROM Resources WHERE Email = {0}", registration.Contact.Email).SingleOrDefault();
RegistrationStatus status = db.RegistrationStatuses.SingleOrDefault(s => s.Name == registration.Status);
DataAccess.Entities.Event _event = null;
if (registration.Event != null)
{
_event = db.Events.SingleOrDefault(e => e.ExternalId == registration.Event.UniqueIdentifier.GetValueOrDefault());
}
AsyncTask asyncTask = _arloService.GetAsyncTask(registration, documentTemplateId);
List<string> errorMessages = new List<string>();
if (contact == null)
{
errorMessages.Add("During the UpsertRegistrations, the Contact was not found with the following Email: " + registration.Contact.Email);
}
if (status == null)
{
errorMessages.Add("During the UpsertRegistrations, the RegistrationStatus was not found with the following Name: " + registration.Status);
}
if (_event == null)
{
if (registration.Event == null)
{
errorMessages.Add("During the UpsertRegistrations, the Event was null for the Registration with the Arlo RegistrationId: " + registration.RegistrationId);
}
else
{
errorMessages.Add("During the UpsertRegistrations, the Event was not found with the following ExternalId: " + registration.Event.UniqueIdentifier);
}
}
if (errorMessages.Any())
{
LambdaLogger.Log(string.Join(". ", errorMessages.ToArray()));
continue;
}
string externalRegistrationId = registration.UniqueIdentifier.ToString();
string certificateUrl = null;
if (asyncTask != null && asyncTask.CertificateDownloadUrls != null)
{
certificateUrl = asyncTask.CertificateDownloadUrls.FirstOrDefault();
}
if (resourceRegistration == null)
{
// insert
resourceRegistration = new ResourceRegistration()
{
Id = Guid.NewGuid(),
ResourceId = contact.Id,
RegistrationStatusId = status.Id,
CourseId = null,
EventId = _event.Id,
ExternalId = externalRegistrationId,
Score = null,
Uri = certificateUrl,
};
db.ResourceRegistrations.Add(resourceRegistration);
}
else
{
// update
resourceRegistration.ResourceId = contact.Id;
resourceRegistration.RegistrationStatusId = status.Id;
resourceRegistration.EventId = _event.Id;
resourceRegistration.ExternalId = externalRegistrationId;
resourceRegistration.Uri = certificateUrl;
}
}
await db.SaveChangesAsync();
}
}
答案 0 :(得分:0)
与同事进行橡皮鸭训练后,我发现了自己的问题。显然存在一个名为18, 2
的时态表,它表示历史数据。在我要写入的表上设置了一个触发器,该触发器会自动将相同的数据写入时态表。
之所以难以调试,是因为返回的错误消息不包含引发转换错误的表的表名。
虽然此错误相对少见,但这是我们调试问题的方法:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.HasAnnotation("ProductVersion", "2.2.6-servicing-10079");
modelBuilder.Entity<Table>(entity =>
{
entity.ToTable("table");
entity.Property(e => e.Id).HasColumnName("id");
entity.Property(e => e.Salary)
.HasColumnName("salary")
.HasColumnType("decimal(18, 0)")
.HasDefaultValueSql("0");
});
}
。Histories.Registrations
上的ExternalId列的属性,以确认该列的数据类型是预期的数据类型。宾果游戏!最后一步是当我们发现错误时。