Linq to entities 不生成 where 子句
Linq to entities is not generating a where clause
这很奇怪,以前从未见过这样的东西。我有一个我有一段时间没有接触过的旧项目,它使用代码优先的 Linq to Entities 进行设置。我尝试从工作中 select 数据的每个实体,但正在生成的 SQL 不包含 where 子句。 (我可以看到 SQL Profiler 中生成的内容)所以应用程序基本上是 selecting 表中的所有行,然后在服务器上进行过滤,这是不好的。我的项目是 .Net Core 2.2 使用 Microsoft.EntityFrameworkCore
汇编版本 2.2.6.0
我觉得这可能是配置错误,但我没有发现任何问题。有人以前见过这样的东西吗?
无论这个问题是什么,在尝试保存国家/地区实体时它也会向我展示此异常;这没有意义,因为 CountryId 是下面代码优先设置中的主键,我绝对不会分配它。
Cannot insert explicit value for identity column in table 'Country' when IDENTITY_INSERT is set to OFF.
我尝试了 selection 的不同变体,其中 none 生成了一个 where 子句。
var country = await _taxContext.Countries
.FirstOrDefaultAsync(a => a.TwoLetterISOCode.Equals(country.jurisCode, StringComparison.OrdinalIgnoreCase))
.ConfigureAwait(false);
-- generates this sql
SELECT [a].[CountryId], [a].[Name], [a].[TwoLetterISOCode]
FROM [dbo].[Country] AS [a]
var exists = await _taxContext.Countries
.AnyAsync(a => a.TwoLetterISOCode.Equals(country.jurisCode, StringComparison.OrdinalIgnoreCase))
.ConfigureAwait(false);
-- generates this sql
SELECT [a].[TwoLetterISOCode]
FROM [dbo].[Country] AS [a]
这是我的国家/地区实体 POCO
public class Country
{
public byte CountryId { get; private set; }
public string Name { get; set; }
public string TwoLetterISOCode { get; set; }
public ICollection<Nexus> Nexi { get; set; }
}
我的国家/地区配置
class CountryConfiguration : IEntityTypeConfiguration<Country>
{
public void Configure(EntityTypeBuilder<Country> builder)
{
builder.ToTable(nameof(Country), "dbo");
builder.HasKey(ci => ci.CountryId);
builder.Property(ci => ci.Name)
.HasColumnType("nvarchar(75)");
builder.Property(ci => ci.TwoLetterISOCode)
.HasColumnType("char(2)");
builder.HasMany(ci => ci.Nexi)
.WithOne(ci => ci.Country);
}
}
和我的 DbContext
public class TaxContext : DbContext
{
public TaxContext(DbContextOptions<TaxContext> options) : base(options)
{
}
public DbSet<Region> Regions { get; set; }
public DbSet<Country> Countries { get; set; }
public DbSet<Nexus> Nexi { get; set; }
public DbSet<TaxRate> FallbackRates { get; set; }
public DbSet<CircuitBreakerLog> CircuitBreakerLogs { get; set; }
public DbSet<AppLog> AppLogs { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder
.ApplyConfiguration(new NexusConfiguration())
.ApplyConfiguration(new RegionConfiguration())
.ApplyConfiguration(new CountryConfiguration())
.ApplyConfiguration(new TaxRateConfiguration())
.ApplyConfiguration(new CircuitBreakerLogConfiguration())
.ApplyConfiguration(new AppLogConfiguration());
}
}
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<TaxContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
}
您应该会在输出中看到警告,表明 EF 正在本地评估您的查询。这是因为您的字符串比较。虽然我将支持使用 string.Equals
,但它不支持您使用的重载。 EF 不知道如何处理 StringComparison.OrdinalIgnoreCase
因为它依赖于大小写、重音等的数据库排序。解决方案是使用简单的重载或基本的 ==
:
.FirstOrDefaultAsync(a => a.TwoLetterISOCode.Equals(country.jurisCode))
或者
.FirstOrDefaultAsync(a => a.TwoLetterISOCode == country.jurisCode)
这很奇怪,以前从未见过这样的东西。我有一个我有一段时间没有接触过的旧项目,它使用代码优先的 Linq to Entities 进行设置。我尝试从工作中 select 数据的每个实体,但正在生成的 SQL 不包含 where 子句。 (我可以看到 SQL Profiler 中生成的内容)所以应用程序基本上是 selecting 表中的所有行,然后在服务器上进行过滤,这是不好的。我的项目是 .Net Core 2.2 使用 Microsoft.EntityFrameworkCore
汇编版本 2.2.6.0
我觉得这可能是配置错误,但我没有发现任何问题。有人以前见过这样的东西吗?
无论这个问题是什么,在尝试保存国家/地区实体时它也会向我展示此异常;这没有意义,因为 CountryId 是下面代码优先设置中的主键,我绝对不会分配它。
Cannot insert explicit value for identity column in table 'Country' when IDENTITY_INSERT is set to OFF.
我尝试了 selection 的不同变体,其中 none 生成了一个 where 子句。
var country = await _taxContext.Countries
.FirstOrDefaultAsync(a => a.TwoLetterISOCode.Equals(country.jurisCode, StringComparison.OrdinalIgnoreCase))
.ConfigureAwait(false);
-- generates this sql
SELECT [a].[CountryId], [a].[Name], [a].[TwoLetterISOCode]
FROM [dbo].[Country] AS [a]
var exists = await _taxContext.Countries
.AnyAsync(a => a.TwoLetterISOCode.Equals(country.jurisCode, StringComparison.OrdinalIgnoreCase))
.ConfigureAwait(false);
-- generates this sql
SELECT [a].[TwoLetterISOCode]
FROM [dbo].[Country] AS [a]
这是我的国家/地区实体 POCO
public class Country
{
public byte CountryId { get; private set; }
public string Name { get; set; }
public string TwoLetterISOCode { get; set; }
public ICollection<Nexus> Nexi { get; set; }
}
我的国家/地区配置
class CountryConfiguration : IEntityTypeConfiguration<Country>
{
public void Configure(EntityTypeBuilder<Country> builder)
{
builder.ToTable(nameof(Country), "dbo");
builder.HasKey(ci => ci.CountryId);
builder.Property(ci => ci.Name)
.HasColumnType("nvarchar(75)");
builder.Property(ci => ci.TwoLetterISOCode)
.HasColumnType("char(2)");
builder.HasMany(ci => ci.Nexi)
.WithOne(ci => ci.Country);
}
}
和我的 DbContext
public class TaxContext : DbContext
{
public TaxContext(DbContextOptions<TaxContext> options) : base(options)
{
}
public DbSet<Region> Regions { get; set; }
public DbSet<Country> Countries { get; set; }
public DbSet<Nexus> Nexi { get; set; }
public DbSet<TaxRate> FallbackRates { get; set; }
public DbSet<CircuitBreakerLog> CircuitBreakerLogs { get; set; }
public DbSet<AppLog> AppLogs { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder
.ApplyConfiguration(new NexusConfiguration())
.ApplyConfiguration(new RegionConfiguration())
.ApplyConfiguration(new CountryConfiguration())
.ApplyConfiguration(new TaxRateConfiguration())
.ApplyConfiguration(new CircuitBreakerLogConfiguration())
.ApplyConfiguration(new AppLogConfiguration());
}
}
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<TaxContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
}
您应该会在输出中看到警告,表明 EF 正在本地评估您的查询。这是因为您的字符串比较。虽然我将支持使用 string.Equals
,但它不支持您使用的重载。 EF 不知道如何处理 StringComparison.OrdinalIgnoreCase
因为它依赖于大小写、重音等的数据库排序。解决方案是使用简单的重载或基本的 ==
:
.FirstOrDefaultAsync(a => a.TwoLetterISOCode.Equals(country.jurisCode))
或者
.FirstOrDefaultAsync(a => a.TwoLetterISOCode == country.jurisCode)