[英]Entity Framework Core 6.0 with database-first approach - unneded column in select when using include
I have an existing database that I'd like to use in my ASP.NET 6 (.NET 6) application.我有一个想要在我的 ASP.NET 6 (.NET 6) 应用程序中使用的现有数据库。
There are two tables that I have problem with:我有两个表有问题:
CREATE TABLE [dbo].[Contacts](
[contactid] [UNIQUEIDENTIFIER] NULL,
[address] [NVARCHAR](100) NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
CREATE TABLE [dbo].[Passwords](
[Id] [UNIQUEIDENTIFIER] NOT NULL,
[UserId] [UNIQUEIDENTIFIER] NOT NULL,
[PasswordHash] [NVARCHAR](MAX) NULL,
CONSTRAINT [PK_dbo.Passwords] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
Relation in one-to-many - one Contact can have multiple Passwords (I store old password hashes).一对多关系 - 一个联系人可以有多个密码(我存储旧密码哈希)。 I can't change tables in the DB and add PK to the Contacts table.
我无法更改数据库中的表并将 PK 添加到联系人表中。
Now inside C#, I have two models:现在在 C# 中,我有两个模型:
public sealed class Contact
{
public Guid ContactId { get; set; }
public string Address { get; set; }
public IEnumerable<Password> Passwords { get; private set; } = new List<StrefaPasswordMemory>();
}
public sealed class Password
{
public Guid Id { get; set; }
public Guid UserId { get; set; }
public string PasswordHash { get; set; }
public Contact Contact { get; set; }
}
My DBContext has this override:我的 DBContext 有这个覆盖:
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<Password>(entity =>
{
entity.ToTable("Passwords");
entity.Property(e => e.Id).ValueGeneratedNever();
entity.Property(e => e.PasswordHash).IsRequired();
//relationships
entity.HasOne(x => x.Contact).WithMany(x => x.Passwords).HasForeignKey(x => x.UserId);
});
builder.Entity<Contact>(entity =>
{
entity.ToTable("Contacts");
//define primary key
entity.HasKey(e => e.ContactId);
entity.HasIndex(e => e.ContactId, "index_contactid").IsUnique();
entity.Property(e => e.Address).HasMaxLength(100).HasColumnName("address");
//relationships
entity.HasMany(x => x.Passwords).WithOne().HasForeignKey(x => x.UserId);
});
}
Now inside code, I can query each separate column, but I'm getting errors when I use Include
.现在在代码中,我可以查询每个单独的列,但是当我使用
Include
时出现错误。
This works just fine:这工作得很好:
var tmp = await _context.Contacts.FirstOrDefaultAsync(x => x.Passwords.Any(y => y.Password == "hashhash"), cancellationToken: cancellationToken);
this however throws an error:然而,这会引发错误:
var all = await _context.Contacts.Include(x => x.Passwords).Where(x=>x.Passwords.Any()).ToListAsync(cancellationToken: cancellationToken);
This is the query that is generated:这是生成的查询:
SELECT [s1].[Id], [s1].[ContactId], [s1].[PasswordHash], [s1].[UserId], [s].[ContactId]
FROM [dbo].[Contacts] AS [s]
INNER JOIN [Passwords] AS [s1] ON [s].[ContactId] = [s1].[UserId]
WHERE EXISTS (
SELECT 1
FROM [Passwords] AS [s0]
WHERE [s].[ContactId] = [s0].[UserId])
ORDER BY [s].[ContactId]
As you can see entity framework is adding ContactId
from Passwords
and this column does not exist in the DB.如您所见,实体框架正在从
Passwords
中添加ContactId
,并且该列在数据库中不存在。
You need to specify the navigation property that points from Password
to Contact
when configuring the relationship:在配置关系时,您需要指定从
Password
指向Contact
的导航属性:
builder.Entity<Contact>(entity =>
{
entity.ToTable("Contacts");
//define primary key
entity.HasKey(e => e.ContactId);
entity.HasIndex(e => e.ContactId, "index_contactid").IsUnique();
entity.Property(e => e.Address).HasMaxLength(100).HasColumnName("address");
//relationships
entity.HasMany(x => x.Passwords).WithOne(x => x.Contact).HasForeignKey(x => x.UserId);
});
However, it is also enough to only specify the relationship for one of the types.但是,仅指定其中一种类型的关系也足够了。 If you define the relation for one type, both of the following statements work:
如果您为一种类型定义关系,则以下两个语句都有效:
var all = await _context.Contacts.Include(x => x.Passwords).Where(x => x.Passwords.Any()).ToListAsync(cancellationToken: cancellationToken);
var others = await _context.Passwords.Include(x => x.Contact).ToListAsync();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.