实体框架将随机 GUID 放入字符串中。数据库保存时字段为空

问题描述 投票:0回答:1

我已经创建了一个完整的 EF 挂钩到我们的一个数据库(我不控制其结构)来执行一些基本的 CRUD 操作。到目前为止,一切都很顺利。但是,我在插入我的一门课程时遇到了问题。它正在尝试将新记录插入名为“applmort”的表中。我不会过多介绍该数据库表的设计方式,因为创建它的不是我的公司。但我们可以访问它并且可以对其进行 CRUD 操作。

该表有一列我称之为

UWT
,它被声明为
varchar(12)
。因此,我设置了 EF 配置,将输入的值限制为 12。您会在我将发布的“配置”文件中注意到这一点。虽然该列是
NOTNULL
,但我可以简单地在该列中放入一个空白
varchar
,一切都很好。对此没有表限制。

因此,当我尝试添加新记录时,我没有在对象中指定此字段。我可以使用表中的一堆其他列来执行此操作,并且由于我的配置文件告诉 EF 插入一个 string.Empty 作为默认值,所以一切都很顺利。除了这个

UWT
专栏。它犹豫不决并告诉我存在截断错误。由于我放入了一个空字符串,这看起来很奇怪。我深入研究并意识到 EF 正在尝试创建此
UWT
列作为备用键,然后用我从未告诉过它使用的随机 GUID 填充它。我追踪到这一点,发现我有另一个表通过配置文件连接到这个表(应该是我在下面列出的第二个配置类)。这个另一个对象通过
UWT
链接到我的应用程序对象。这应该是正常的,我不认为把它放进去会引起问题。然而,确实如此。当我从第二个对象中删除“一对多”以断开链接时,记录会正确插入。

我发现的另一个解决方法是在应用程序对象上的

UWT
列指定为空白字符串,然后再达到配置中的默认值。这也允许毫无问题地插入记录。

我可以使用这些解决方法中的任何一个。第二个效果最好,可以让我保留我的表格链接。但这看起来非常非常奇怪。我创建的任何其他表链接都不会发生这种情况,所以我必须问:我在这里做错了什么吗?我是否在某处设置了一些导致 GUID 被推入非常明显的非 GUID 列的内容?我一生都找不到这个。

public class Application
{
    public DateTime? ChangeDate { get; set; }
    public int ID { get; set; }
    public DateTime? ApplicationDate { get; set; }
    public string StructureID { get; set; } = null!;
    public string UWT { get; set; } = null!;
    public int UnitNumber { get; set; }
    
    public virtual Structure Structure { get; set; } = null!;
    public virtual ICollection<ApplicationHold> ApplicationHolds { get; set; } = [];
}

public class ApplicationHold
{
    public DateTime? ChangeDate { get; set; }
    public string UWT { get; set; } = null!;
    public int ID { get; set; }

    public virtual Application Application { get; set; } = null!;
}

public class ApplicationConfig : IEntityTypeConfiguration<Application>
{
    public void Configure(EntityTypeBuilder<Application> entity)
    {
        entity.ToTable("applmort");

        entity.HasKey(e => e.ID);

        entity.Property(e => e.ChangeDate)
            .HasColumnName("changedate")
            .HasColumnType("datetime")
            .HasDefaultValue(DateTime.Now)
            .IsRequired();
        entity.Property(e => e.ID)
            .HasColumnName("id")
            .UseIdentityColumn();
        entity.Property(e => e.ApplicationDate)
            .HasColumnName("appldate")
            .HasColumnType("datetime")
            .HasDefaultValue(DateTime.Now);
        entity.Property(e => e.StructureID)
            .HasColumnName("stru")
            .HasMaxLength(3)
            .HasDefaultValue(string.Empty)
            .IsRequired();
        entity.Property(e => e.UWT)
            .HasColumnName("uwt")
            .HasColumnType("varchar")
            .HasMaxLength(12)
            .HasDefaultValue(string.Empty)
            .IsRequired();
        entity.Property(e => e.UnitNumber)
            .HasColumnName("units")
            .HasColumnType("int")
            .HasDefaultValue(0)
            .IsRequired();

        entity.HasOne(e => e.Structure).WithMany(e => e.Applications)
            .HasForeignKey(e => e.LoanStructureID)
            .HasPrincipalKey(e => e.LoanStructureID)
            .IsRequired(false)
            .OnDelete(DeleteBehavior.NoAction);
    }
}

public class ApplicationHoldConfig : IEntityTypeConfiguration<ApplicationHold>
{
    public void Configure(EntityTypeBuilder<ApplicationHold> entity)
    {
        entity.ToTable("applhold");

        entity.HasKey(e => e.ID);

        entity.Property(e => e.ChangeDate)
            .HasColumnName("changedate")
            .HasColumnType("datetime")
            .HasDefaultValue(DateTime.Now)
            .IsRequired();
        entity.Property(e => e.ID)
            .HasColumnName("id")
            .UseIdentityColumn();
        entity.Property(e => e.UWT)
            .HasColumnName("uwt")
            .HasColumnType("varchar")
            .HasMaxLength(12)
            .HasDefaultValue(string.Empty)
            .IsRequired();

        entity.HasOne(entity => entity.Application).WithMany(e => e.ApplicationHolds)
            .HasForeignKey(entity => entity.UWT)
            .HasPrincipalKey(e => e.UWT)
            .IsRequired(false)
            .OnDelete(DeleteBehavior.NoAction);
    }
}
c# sql .net entity-framework
1个回答
0
投票

EF 试图通过它如何理解 Application 和 ApplicationHold 之间的关系来对 UWT 字段进行唯一约束

您可以尝试不使用 HasDefaultValue(string.Empty),因为似乎即使拥有此代码也足以使 EF 自动生成关系,并删除默认值配置并在您的应用程序中处理它们。

entity.Property(e => e.UWT)
            .HasColumnName("uwt")
            .HasColumnType("varchar")
            .HasMaxLength(12)
            .HasDefaultValue(string.Empty) 
            .IsRequired();

直接设置此值应该可以解决插入记录时的问题

Application application = new()
{
    UWT = string.Empty, 
};
© www.soinside.com 2019 - 2024. All rights reserved.