我想在我的控制器中设置一个 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) 使用 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 个选项的选择。
我做了一个小测试,启用惰性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 行。
可以做些什么来获得良好的性能?
我想并行执行几个 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) 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) 关于在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?
我们在 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
这是我的 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: …
我目前正在试用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# 代码中执行操作时,我都会保存新的 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)