简体   繁体   English

具有数据库优先方法的 Entity Framework Core 6.0 - 使用包含时选择中的未定义列

[英]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.

相关问题 在实体框架中刷新使用数据库优先方法模型创建的实体中的数据 - Refresh the data in entity created using database-first approach model in Entity Framework 实体框架中没有自动生成代码的数据库优先方法 - Database-first approach in Entity Framework without auto generated code 数据库优先方法中的Linq-to-SQL与实体框架 - Linq-to-SQL vs Entity Framework in database-first approach 实体框架数据库优先方法有条件地插入数据 - Entity Framework database-first approach conditionally insert data Entity Framework Core 数据库优先选择特定列 - Entity Framework Core database-first selecting specific columns 实体框架数据库优先和列属性不起作用 - Entity Framework database-first and column attribute does not work 对数据库优先实体框架模型的更改 - Changes to a database-first Entity Framework model 在“实体框架”数据库优先方法中,将“默认值1”设置为EntityName(状态) - Set Default Value 1 to an EntityName (Status) in Entity Framework database-first approach 具有输出参数和结果集的实体框架数据库优先方法存储过程 - Entity framework database-first approach stored procedure with output parameter and result set 是否存在实体框架7数据库优先POCO生成器? - Is there an Entity Framework 7 Database-First POCO Generator?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM