【问题标题】:EF Core 2.0 - System.NotSupportedException On Add [duplicate]EF Core 2.0-添加时的 System.NotSupportedException [重复]
【发布时间】:2018-03-16 05:31:18
【问题描述】:

我使用的是 EF Core 2.0。我有一个有 4 列的表,其中 PK 由所有 4 列组成。其中一列 (IsDefault) 是数据库中的位字段。如果我插入一条 IsDefault 设置为 true 的记录,一切正常。如果我插入一条 IsDefault 设置为 false 的记录,我会收到以下异常:

System.NotSupportedException occurred
  HResult=0x80131515
  Message=The 'IsDefault' on entity type 'ChromeMileageRestrictionTest' does not have a value set and no value generator is available for properties of type 'bool'. Either set a value for the property before adding the entity or configure a value generator for properties of type 'bool'.
  Source=<Cannot evaluate the exception source>
  StackTrace:
   at Microsoft.EntityFrameworkCore.ValueGeneration.ValueGeneratorSelector.Create(IProperty property, IEntityType entityType)
   at Microsoft.EntityFrameworkCore.ValueGeneration.RelationalValueGeneratorSelector.Create(IProperty property, IEntityType entityType)
   at Microsoft.EntityFrameworkCore.ValueGeneration.Internal.SqlServerValueGeneratorSelector.Create(IProperty property, IEntityType entityType)
   at Microsoft.EntityFrameworkCore.ValueGeneration.ValueGeneratorSelector.<>c__DisplayClass6_0.<Select>b__0(IProperty p, IEntityType e)
   at Microsoft.EntityFrameworkCore.ValueGeneration.ValueGeneratorCache.<>c.<GetOrAdd>b__3_0(CacheKey ck)
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
   at Microsoft.EntityFrameworkCore.ValueGeneration.ValueGeneratorCache.GetOrAdd(IProperty property, IEntityType entityType, Func`3 factory)
   at Microsoft.EntityFrameworkCore.ValueGeneration.ValueGeneratorSelector.Select(IProperty property, IEntityType entityType)
   at Microsoft.EntityFrameworkCore.ValueGeneration.Internal.SqlServerValueGeneratorSelector.Select(IProperty property, IEntityType entityType)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.ValueGenerationManager.Generate(InternalEntityEntry entry)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.SetEntityState(EntityState entityState, Boolean acceptChanges, Boolean forceStateWhenUnknownKey)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityGraphAttacher.PaintAction(EntityEntryGraphNode node)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityEntryGraphIterator.TraverseGraph(EntityEntryGraphNode node, Func`2 handleNode)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityGraphAttacher.AttachGraph(InternalEntityEntry rootEntry, EntityState entityState, Boolean forceStateWhenUnknownKey)
   at Microsoft.EntityFrameworkCore.DbContext.SetEntityState(InternalEntityEntry entry, EntityState entityState)
   at Microsoft.EntityFrameworkCore.DbContext.SetEntityState[TEntity](TEntity entity, EntityState entityState)
   at Microsoft.EntityFrameworkCore.DbContext.Add[TEntity](TEntity entity)
   at DAL.Tests.UnitTest1.TestMethod1() in C:\Users\jkruer\Source\Repos\JLM.App.ChromeIncentivesService\DAL.Tests\UnitTest1.cs:line 12

我创建了一个非常简化的版本,并且能够通过我的单个表、单个实体、单个记录、单个单元测试实现来重现问题。

我的数据库表:

CREATE TABLE [dbo].[ChromeMileageRestrictionTEST](
    [TermID] [varchar](50) NOT NULL,
    [Mileage] [varchar](50) NOT NULL,
    [Residual] [decimal](18, 8) NOT NULL,
    [isDefault] [bit] NOT NULL,
 CONSTRAINT [PK_ChromeMileageRestrictionTEST] PRIMARY KEY CLUSTERED 
(
    [TermID] ASC,
    [Mileage] ASC,
    [Residual] ASC,
    [isDefault] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

ALTER TABLE [dbo].[ChromeMileageRestrictionTEST] ADD  CONSTRAINT [DF_ChromeMileageRestrictionTEST_Residual]  DEFAULT ((0)) FOR [Residual]
GO

ALTER TABLE [dbo].[ChromeMileageRestrictionTEST] ADD  CONSTRAINT [DF_ChromeMileageRestrictionTEST_isDefault]  DEFAULT ((0)) FOR [isDefault]
GO

我的数据库上下文:

public partial class ReportingContext : DbContext
    {
        public ReportingContext()
        {
        }

        public virtual DbSet<ChromeMileageRestrictionTest> ChromeMileageRestriction { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlServer(@"MyConnectionStringGoesHere");            
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<ChromeMileageRestrictionTest>(entity =>
            {
                entity.HasKey(e => new { e.TermId, e.Mileage, e.Residual, e.IsDefault })                
                .HasName("PK_ChromeMileageRestrictionTest");

                entity.Property(e => e.TermId)
                    .HasColumnName("TermID")
                    .HasMaxLength(50)
                    .IsUnicode(false);

                entity.Property(e => e.Mileage)
                    .HasMaxLength(50)
                    .IsUnicode(false);

                entity.Property(e => e.Residual)
                    .HasColumnType("decimal(18, 8)")
                    .HasDefaultValueSql("((0))");

                entity.Property(e => e.IsDefault)
                    .HasColumnName("isDefault")
                    .HasDefaultValueSql("((0))");
            });
        }
    }

我的实体:

public partial class ChromeMileageRestrictionTest
    {
        public string TermId { get; set; }
        public string Mileage { get; set; }
        public decimal Residual { get; set; }
        public bool IsDefault { get; set; }
    }

我的单元测试:

[TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void TestMethod1()
        {
            var dbContext = new ReportingContext();
            dbContext.Add(new ChromeMileageRestrictionTest 
            {
                TermId = "6078915-0-0",
                Mileage = "15,000",
                Residual = 45.00000000M,
                IsDefault = true //THIS WORKS
            });
            dbContext.Add(new ChromeMileageRestrictionTest 
            {
                TermId = "6078915-0-0",
                Mileage = "15,000",
                Residual = 45.00000000M,
                IsDefault = false //THIS THROWS AN EXCEPTION
            });
            dbContext.SaveChanges();
        }
    }

我在这个问题上摸不着头脑已经有一段时间了。我想不通。任何帮助将不胜感激!

谢谢!

【问题讨论】:

  • 您是否为了测试而将ChromeMileageRestrictionTest 中的类型更改为byte 并在位列中插入1 或0?由于您只有一个位字段 - 您也可以尝试在数据库中使用 tinyint 字段。
  • 您添加了两次相同的记录,看起来是这样。尝试编辑其中一些数据,使其不完全相同。如果您的 PK 在所有这些列上,那么它们不应该是唯一的吗?我认为您的错误是误报,真正的潜在问题是您正在编写的这些数据不是唯一的,它需要是
  • 您同时添加了两条记录,尝试添加一条并保存,然后添加下一条并保存。所以两个 SaveChanges 而不是一个
  • @fredrik 不是 EntityFramework 在数据库中使用 bool 属性和位字段的标准约定吗?我不认为我完全理解你的建议。
  • 看这个:github.com/aspnet/EntityFrameworkCore/issues/7163 这是一个备受争议的问题。我不明白这里的 EF 课程。或者这个:github.com/aspnet/EntityFrameworkCore/issues/8540

标签: c# sql-server entity-framework .net-core entity-framework-core


【解决方案1】:

此副本:Entity Framework not including columns with default value in insert into query

TLDR:我从数据库和 DbContext 映射中删除了 IsDefault 字段的默认值 False。这样就解决了问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-08
    • 1970-01-01
    • 1970-01-01
    • 2019-01-03
    • 2022-01-13
    • 1970-01-01
    • 2022-01-13
    • 2018-04-30
    相关资源
    最近更新 更多