c# - Entity Framework 核心错误?

标签 c# entity-framework entity-framework-core

如果这是 Entity Framework Core 中的错误,谁能证实这一点?

SQL:

CREATE TABLE [dbo].[Users]
(
    [CreatedById] [UNIQUEIDENTIFIER] NOT NULL,
    [UpdatedById] [UNIQUEIDENTIFIER] NULL,
    [Id] [UNIQUEIDENTIFIER] NOT NULL,
    [Name] [NVARCHAR](150) NOT NULL,

    CONSTRAINT [PK_Users] 
        PRIMARY KEY CLUSTERED ([Id] ASC)
) ON [PRIMARY]
GO

ALTER TABLE [dbo].[Users]  WITH CHECK 
    ADD CONSTRAINT [FK_Users_Users_CreatedById] 
        FOREIGN KEY([CreatedById]) REFERENCES [dbo].[Users] ([Id])
GO

ALTER TABLE [dbo].[Users] WITH CHECK 
    ADD CONSTRAINT [FK_Users_Users_UpdatedById] 
        FOREIGN KEY([UpdatedById]) REFERENCES [dbo].[Users] ([Id])
GO

示例数据:

INSERT [dbo].[Users] ([CreatedById], [UpdatedById], [Id], [Name]) 
VALUES (N'2cfc1025-cf96-4929-a6a4-e2ed77a6ae12', N'2cfc1025-cf96-4929-a6a4-e2ed77a6ae12', N'2cfc1025-cf96-4929-a6a4-e2ed77a6ae12', N'Admin'),
       (N'2cfc1025-cf96-4929-a6a4-e2ed77a6ae12', N'60ca72c4-db2d-4cea-9981-c10d6942a11e', N'60ca72c4-db2d-4cea-9981-c10d6942a11e', N'User 01'),
       (N'60ca72c4-db2d-4cea-9981-c10d6942a11e', NULL, N'40719114-f53e-4d3f-9a1b-49f63b18002b', N'New User')

模型

  [Table("Users")]
    public partial class User 
    {
        [Required]
        public Guid Id { get; set; }
        [Required]
        [MaxLength(150)]
        public string Name { get; set; }
        [Required]
        public User CreatedBy { get; set; }
        public User UpdatedBy { get; set; }
        [Required]
        public Guid CreatedById { get; set; }
        public Guid? UpdatedById { get; set; }

    }

Entity Framework 6.2 (.EDMX) 代码:

using (var context = new Agap2TestEntities())
{
   var test = context.Users.Include(p => p.User1).Include(p =>p.User2).ToList();
   Console.WriteLine(test.Count);
}

SQL 生成

   SELECT
        1 AS [C1],
        [Extent1].[CreatedById] AS [CreatedById],
        [Extent1].[UpdatedById] AS [UpdatedById],
        [Extent1].[Id] AS [Id],
        [Extent1].[Name] AS [Name],
        [Extent2].[CreatedById] AS [CreatedById1],
        [Extent2].[UpdatedById] AS [UpdatedById1],
        [Extent2].[Id] AS [Id1],
        [Extent2].[Name] AS [Name1],
        [Extent3].[CreatedById] AS [CreatedById2],
        [Extent3].[UpdatedById] AS [UpdatedById2],
        [Extent3].[Id] AS [Id2],
        [Extent3].[Name] AS [Name2]
        FROM   [dbo].[Users] AS [Extent1]
        INNER JOIN [dbo].[Users] AS [Extent2] ON [Extent1].[CreatedById] = [Extent2].[Id]
        LEFT OUTER JOIN [dbo].[Users] AS [Extent3] ON [Extent1].[UpdatedById] = [Extent3].[Id]

返回3条记录,没问题!

Entity Framework 核心 2.1.4

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

    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) {}
}

class Program
{
    private static ApplicationDbContext CreateContext()
    {
         return new ApplicationDbContext(new DbContextOptionsBuilder<ApplicationDbContext>().UseSqlServer("Server=...").Options);
    }

    static void Main(string[] args)
    {
        using (var dbContext = CreateContext())
        {
            var test = dbContext.Set<User>().Include(p => p.CreatedBy).Include(p => p.UpdatedBy).ToList();
            Console.WriteLine(test.Count);
        }
   }
}

SQL 生成

SELECT [p].[Id], [p].[CreatedById], [p].[Name], [p].[UpdatedById], [p.UpdatedBy].[Id], [p.UpdatedBy].[CreatedById], [p.UpdatedBy].[Name], [p.UpdatedBy].[UpdatedById], [p.CreatedBy].[Id], [p.CreatedBy].[CreatedById], [p.CreatedBy].[Name], [p.CreatedBy].[UpdatedById]
FROM [Users] AS [p]
LEFT JOIN [Users] AS [p.UpdatedBy] ON [p].[Id] = [p.UpdatedBy].[CreatedById]
INNER JOIN [Users] AS [p.CreatedBy] ON [p].[CreatedById] = [p.CreatedBy].[Id]

返回4条记录,KO!

这一行“LEFT JOIN [Users] AS [p.UpdatedBy] ON [p].[Id] = [p.UpdatedBy].[CreatedById]”是错误的!

有人知道为什么会这样吗?

提前致谢!

最佳答案

我无法重现。 A 运行该 SQL 并从数据库构建模型。查询

 db.Set<Users>().Include(p => p.CreatedBy).Include(p => p.UpdatedBy).ToList();

正确翻译为

SELECT [p].[Id], [p].[CreatedById], [p].[Name], [p].[UpdatedById], [p.UpdatedBy].[Id], [p.UpdatedBy].[CreatedById], [p.UpdatedBy].[Name], [p.UpdatedBy].[UpdatedById], [p.CreatedBy].[Id], [p.CreatedBy].[CreatedById], [p.CreatedBy].[Name], [p.CreatedBy].[UpdatedById]
FROM [Users] AS [p]
LEFT JOIN [Users] AS [p.UpdatedBy] ON [p].[UpdatedById] = [p.UpdatedBy].[Id]
INNER JOIN [Users] AS [p.CreatedBy] ON [p].[CreatedById] = [p.CreatedBy].[Id]

这里是生成的 DbContext:

using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;

namespace EfCoreTest
{
    public partial class FooContext : DbContext
    {
        public FooContext()
        {
        }

        public FooContext(DbContextOptions<FooContext> options)
            : base(options)
        {
        }

        public virtual DbSet<Users> Users { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            if (!optionsBuilder.IsConfigured)
            {
                optionsBuilder.UseSqlServer("server=.;database=Foo;Integrated Security=true");
            }
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Users>(entity =>
            {
                entity.Property(e => e.Id).ValueGeneratedNever();

                entity.Property(e => e.Name)
                    .IsRequired()
                    .HasMaxLength(150);

                entity.HasOne(d => d.CreatedBy)
                    .WithMany(p => p.InverseCreatedBy)
                    .HasForeignKey(d => d.CreatedById)
                    .OnDelete(DeleteBehavior.ClientSetNull);

                entity.HasOne(d => d.UpdatedBy)
                    .WithMany(p => p.InverseUpdatedBy)
                    .HasForeignKey(d => d.UpdatedById);
            });
        }
    }
}

和生成的实体类:

using System;
using System.Collections.Generic;

namespace EfCoreTest
{
    public partial class Users
    {
        public Users()
        {
            InverseCreatedBy = new HashSet<Users>();
            InverseUpdatedBy = new HashSet<Users>();
        }

        public Guid CreatedById { get; set; }
        public Guid? UpdatedById { get; set; }
        public Guid Id { get; set; }
        public string Name { get; set; }

        public Users CreatedBy { get; set; }
        public Users UpdatedBy { get; set; }
        public ICollection<Users> InverseCreatedBy { get; set; }
        public ICollection<Users> InverseUpdatedBy { get; set; }
    }
}

关于c# - Entity Framework 核心错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52742645/

相关文章:

c# - 每个站点所有打开的选项卡仅浏览器通知一次

c# - 如何以正确的方式初始化 KeyValuePair 对象?

c# - 透明代理 - 从端口 80 到 443

entity-framework - 是否必须在异步 EF 上等待 SaveChangesAsync()?

c# - MemoryStream - 无法访问已关闭的流

c# - 如何使用 EF 从列表中检查不添加重复项

c# - Entity Framework ,鉴别器列,但没有继承

c# - 添加属性以在 Entity Framework Core 中配置小数精度

entity-framework-core - dotnet ef 工具自 vs2017/netcore1.1 起不起作用

c# - ReflectionTypeLoadException 在程序包管理器控制台中运行添加迁移命令时出错