标签: ef-core-2.1

EFCore:简单属性更新期间的实体关联错误

我想在我的控制器中设置一个 bool 属性并将其保存到数据库中。EF 会引发有关其他甚至未修改的属性的错误。

实体“User”和“RequestDetail”与键值为“System.InvalidOperationException”之间的关联:实体“User”和“RequestDetail”与键值为“{Id: 40}”之间的关联已被切断,但关系是标记为“必需”或隐式必需,因为外键不可为空。如果在切断所需关系时应删除依赖/子实体,则将关系设置为使用级联删除。

如果我用一个附加参数调用我的方法,它必须更改一个 RequestDetail 记录的 RequestSent 属性,这很好用。但是在没有此附加参数的情况下调用该方法必须更改多个 RequestDetail 记录上的此属性。这就是它抛出错误的地方。我不会修改与用户相关的任何内容。如果它必须一次做更多的记录,它会抛出这个错误。即使我使用 FirstOrDefaults() 和立即 SaveChanges() 将 foreach 重写为一段时间,它也会在第二轮引发错误。

我的方法:

var head = await _ctx.RequestHeads.FirstOrDefaultAsync(x=>x.Id == d.Id);
if (!d.DetailId.HasValue) {
            var details = _ctx.RequestDetails.Include(x=>x.BuyerUser)
                            .Where(x=>x.RequestHeadId == head.Id); 
//not working, always throws an error if it has to modify more than one record
            await details.ForEachAsync(detail => {
                detail.RequestSent = true;
            });
        } else {
            var detail = head.Details.FirstOrDefault(x=>x.Id == d.DetailId.Value); //works ok, always
            detail.RequestSent = true;
        }
        await _ctx.SaveChangesAsync();
Run Code Online (Sandbox Code Playgroud)

我的模型:

public …
Run Code Online (Sandbox Code Playgroud)

c# entity-framework entity-framework-core ef-core-2.1

6
推荐指数
1
解决办法
8919
查看次数

HasDefaultValue 与从构造函数设置默认值

使用 EF Core 时,我们可以设置属性的默认值。

public class Foo
{
    public int Bar { get; set; }
}

public class FooConfiguration : IEntityTypeConfiguration<Foo>
{
    public void Configure(EntityTypeBuilder<Foo> builder)
    {
        builder.Property(s => s.Bar).HasDefaultValue(1337);
    }
}
Run Code Online (Sandbox Code Playgroud)

我们什么时候应该更喜欢使用HasDefaultValue类中的默认值而不是初始化类内的默认值?

public class Foo
{
    public int Bar { get; set; } = 1337;

    // or inside constructor...
    // public Foo { Bar = 1337; }
}
Run Code Online (Sandbox Code Playgroud)

或者我们应该两者都做?但在这种情况下,HasDefaultValue似乎是多余的。这似乎是一个只能选择 1 个选项的选择。

c# entity-framework-core ef-core-2.1

6
推荐指数
1
解决办法
6050
查看次数

EF Core 延迟加载速度极慢

我做了一个小测试,启用惰性loading.optionsBuilder.UseLazyLoadingProxies().UseSqlServer(ConnectionString);

(使用 EF Core 2.1.4)

我循环浏览有和没有的仪器,这是我得到的结果

情况1

var instruments = db.instruments.OrderBy(t=>t.id).Include(t=>t.NavPro1).ThenInclude(t=>t.NavPro2).Take(200);
Run Code Online (Sandbox Code Playgroud)

案例2

var instruments = db.instruments.OrderBy(t=>t.id).Include(t=>t.NavPro1).ThenInclude(t=>t.NavPro2).Take(200);
Run Code Online (Sandbox Code Playgroud)

然后

   foreach (var i in instruments)
   {
        var props = i.NavPro1;
        foreach (var prop in props)
        {
            sbPrintGreeks.AppendLine(prop.NavPro2.Name + " - " + prop.id + " - " + prop.Value);
        }
   }
Run Code Online (Sandbox Code Playgroud)

无需延迟加载,只需 7 秒即可获取 100k 行

使用延迟加载需要 160 秒才能获取 3k 行。

可以做些什么来获得良好的性能?

c# ef-core-2.1

6
推荐指数
1
解决办法
4144
查看次数

EFCore FromSql 异步

我想并行执行几个 SELECT 存储过程调用。我设置我的上下文如下:

public virtual DbSet<Task<GetCaseCaseContextModel>> CaseGetCaseContextData { get; set; }
Run Code Online (Sandbox Code Playgroud)

然后我的 repo 类执行以下操作:

public async Task<List<GetCaseNotesContextModel>> GetCaseNotes(string caseId)
{
    var notes = _context.CaseGetCaseContextData.FromSql("x_Fortellis_CaseGetCaseNotes @p0", caseId, caseId).ToListAsync();

    return notes;
}
Run Code Online (Sandbox Code Playgroud)

但我收到以下错误:

严重性代码描述项目文件行抑制状态错误CS0029无法隐式转换类型'System.Threading.Tasks.Task<System.Collections.Generic.List<System.Threading.Tasks.Task<CaseManagement.Infrastruct.Database.Repo.Case.GetCase .GetCaseCaseContextModel>>>' 到 'System.Collections.Generic.List<CaseManagement.Infrastruct.Database.Repo.Case.GetCase.GetCaseNotesContextModel>' CaseManagement.Infrastruct.Database C:\Dev\Bitbucket\webscv\Fortellis\CaseManagement\CaseManagement .Infrustruct.Database\Repo\Case\GetCase\GetCaseRepoHelper.cs 72 活动

当我将上下文更改为:

public virtual Task<DbSet<GetCaseCaseContextModel>> CaseGetCaseContextData { get; set; }
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

严重性代码说明项目文件行抑制状态错误 CS1061“Task<DbSet>”不包含“FromSql”的定义,并且找不到接受类型“Task<DbSet>”的第一个参数的可访问扩展方法“FromSql”(是您缺少 using 指令或程序集引用吗?) CaseManagement.Infrastruct.Database C:\Dev\Bitbucket\webscv\Fortellis\CaseManagement\CaseManagement.Infrustruct.Database\Repo\Case\GetCase\GetCaseRepoHelper.cs 70 活动

我最终想使用以下方式致电他们:

GetCaseCaseContextModel caseData = new GetCaseCaseContextModel();
List<GetCaseNotesContextModel> notes = new List<GetCaseNotesContextModel>();

Parallel.Invoke(
    async () => caseData = await GetCaseData(caseId, dealerGroupId),
    async () …
Run Code Online (Sandbox Code Playgroud)

entity-framework-core ef-core-2.0 ef-core-2.1

6
推荐指数
1
解决办法
1万
查看次数

EF Core 2.1 中的 COUNT(DISTINCT *)

SELECT
  e.EmpName,
  me.RemarkNumber,
  me.RemarkPeopleNumber
FROM
  EmployeeInfo e
  LEFT JOIN (
    SELECT
      COUNT(RemarkId) As RemarkNumber,
      COUNT(DISTINCT MemberId) As RemarkPeopleNumber,
      CreateUser
    FROM
      MemberRemark
    WHERE
      RemarkStatus = 0
    GROUP BY
      CreateUser
  ) AS me On e.EmpName = me.CreateUser
WHERE
  BranchCode = '0000'
  And [Status] = 0
Run Code Online (Sandbox Code Playgroud)

如何将其转换为 LINQ?

from e in db.EmployeeInfo
join me in (
    from memberRemarks in db.MemberRemark
    where memberRemarks.RemarkStatus == 0
    group memberRemarks by new
    {
        memberRemarks.CreateUser,
    } into g
    select new
    {
        RemarkNumber = g.Count(),
        RemarkPeopleNumber = g.Select(m => …
Run Code Online (Sandbox Code Playgroud)

c# linq asp.net-core-2.1 ef-core-2.1

5
推荐指数
1
解决办法
1656
查看次数

使用实体框架核心设置更新时级联约束

关于在Entity Framework 核心中为外键关系设置删除动作的行为,有大量信息。但是,关于如何指定外键的“在更新级联”约束,我还没有找到几乎零的细节。

我发现的最接近的是这种迁移相关的Microsoft文档。

public void Configure(EntityTypeBuilder<Something> builder)
        {
             builder
                .HasOne(s => s.Thing)
                .WithMany(t => t.Somethings)
                .HasForeignKey(s => s.ThingId)
                --> Like Delete behavior, how to set update behavior?
                .OnDelete(DeleteBehavior.Cascade);
        }
Run Code Online (Sandbox Code Playgroud)

}

如何使用Fluent API?

entity-framework ef-core-2.1

5
推荐指数
1
解决办法
1638
查看次数

在 EF Core 映射上添加唯一索引似乎不起作用

我们在 ASP.NET 核心 API 解决方案中使用 EF Core。数据库中有一个事务表,并且有一个包含两列的唯一索引。因此,该表中不应有这些列具有相同值的记录。

在我们的 EF 映射中,我们有这个

        builder.HasIndex(e => new { e.RsaSessionId, e.SessionId }).IsUnique(true).HasName("IX_Transactions");

        builder.Property(e => e.RsaSessionId)
            .HasColumnName(nameof(Transaction.RsaSessionId))
            .IsRequired();

        builder.Property(e => e.SessionId)
            .HasColumnName(nameof(Transaction.SessionId))
            .IsRequired()
            .HasColumnType("uniqueidentifier");
Run Code Online (Sandbox Code Playgroud)

但是在我们使用内存数据库提供程序的集成测试中,当在 DbContext 的 Transactions DbSet 中添加两个相同的事务对象时,不会引发错误。这段代码不应该引发错误,因为我们已经指定了一个包含这两列的唯一键吗?

var rsaSessionID=1;
Guid issuerSessionId=Guid.NewGuid();

//create two transactions with the same values for the two fields in the unique index
    var transaction = new Transaction(rsaSessionID, issuerSessionId, ... other fields ... );
    var transaction = new Transaction(rsaSessionID, issuerSessionId, ... other fields ... );
    this.fixture.Context.Transactions.Add(transaction);
this.fixture.Context.Transactions.Add(transaction2);
this.fixture.Context.SaveChanges();
Run Code Online (Sandbox Code Playgroud)

任何帮助是极大的赞赏。

.net integration-testing .net-core asp.net-core-webapi ef-core-2.1

5
推荐指数
1
解决办法
1412
查看次数

.Net Core 2 EF core 连接串问题

这是我的 appsettings.json

 "ConnectionStrings": {
    "Circolari": "Server=abcde;Database=Circolari;Trusted_Connection=True;"
  }
Run Code Online (Sandbox Code Playgroud)

这是我的startup.cs

 public Startup(IConfiguration configuration, IHostingEnvironment env)
 {
        Configuration = configuration;
        IConfigurationBuilder configurationBuilder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
        Configuration = configurationBuilder.Build();
 }


 // This method gets called by the runtime. Use this method to add services to the container.

    public void ConfigureServices(IServiceCollection services)
    {
        //Circolari
        string connectoionString = Configuration.GetConnectionString("Circolari");
        services.AddDbContext<CircolariContext>(options => options.UseSqlServer(connectoionString));
        services.AddMvc();
    }
Run Code Online (Sandbox Code Playgroud)

所以当我进行查询时

using (CircolariContext db = new CircolariContext(new DbContextOptions<CircolariContext>()))
{
   List<Argomenti> listaArgomenti = db.Argomenti.ToList();
}
Run Code Online (Sandbox Code Playgroud)

我有问题:处理请求时发生未处理的异常。

InvalidOperationException: …

c# entity-framework ef-core-2.0 ef-core-2.1

5
推荐指数
2
解决办法
4978
查看次数

实体框架核心-一般设置值转换器

我目前正在试用Entity Framework Core 2.1,以期在我工作的公司的业务应用程序中使用它。我已经在测试项目中实现了价值转换器的大部分方法,但是我现有的知识库使我无奈了!

我想做什么

我的理解是,对于枚举值,内置的类型转换器可以将枚举值转换为等效的字符串(EnumToStringConverter),也可以从枚举值转换为其数值表示形式(EnumToNumberConverter)。但是,我们使用自定义字符串值表示数据库中的枚举,因此我编写了一个自定义EnumToDbStringEquivalentConvertor进行此转换,并且数据库字符串值被指定为模型中每个枚举值的属性。

代码如下:

模型

public class User
{
    [Key] public int ID { get; set; }
    public EmployeeType EmployeeType { get; set; }
}

public enum EmployeeType
{
    [EnumDbStringValue("D")]
    Director,
    [EnumDbStringValue("W")]
    Weekly,
    [EnumDbStringValue("S")]
    Salaried
}
Run Code Online (Sandbox Code Playgroud)

数据上下文

public class MyDataContext : DbContext
{
    public DbSet<User> Users { get; set; }

    foreach (var entityType in modelBuilder.Model.GetEntityTypes())
    {
            foreach (var property in entityType.GetProperties())
            {
                if (property.ClrType.IsEnum)
                {
                    property.SetValueConverter(new EnumToDbStringEquivalentConvertor<EmployeeType>());
                }
             }
         }
    }
}
Run Code Online (Sandbox Code Playgroud)

价值转换器

public class EnumToDbStringEquivalentConvertor<T> : …
Run Code Online (Sandbox Code Playgroud)

c# entity-framework-core ef-core-2.1

5
推荐指数
1
解决办法
2421
查看次数

带有 EF Core 2.1 和 Sql Server 的时间戳?

我想在我的大多数表上基本上都有一个“上次更新”列,以便我可以快速检查它上次更新的时间。

现在我只是放置一个日期时间,每次我在 C# 代码中执行操作时,我都会保存新的 DateTime 以更新该字段。当然,这会导致我忘记这样做。

我想要更自动化的东西。我真的不需要这个用于审计目的,所以它不需要太先进。

我试过

builder.Property(x => x.RowVersion).IsRowVersion();
Run Code Online (Sandbox Code Playgroud)

什么应该制作时间戳,但是当我查看数据库时,我看到0x00000000000007D1我认为它看起来更像日期时间。

编辑

 public class CompanyConfig : IEntityTypeConfiguration<Company>
    {
        public void Configure(EntityTypeBuilder<Company> builder)
        {
            builder.HasKey(x => x.Id);
            builder.Property(x => x.Id).ValueGeneratedOnAdd();
            builder.Property<DateTime>("LastUpdated");
        }
    }
Run Code Online (Sandbox Code Playgroud)

entity-framework ef-code-first ef-core-2.1

5
推荐指数
1
解决办法
1461
查看次数