0

我正在将 ASP .Net Core 2.1 应用程序迁移到 ASP .NET 5.0,但我在实体框架方面遇到了麻烦。如果我在 MySQL 中执行相同的查询,我的应用程序中的结果与结果不匹配

我有这个查询

puestoCajas = _dataContext.puestocajas
    .Include(x => x.ObjSite)
    .Include(x => x.ObjCajaState)
    .Where(x => x.Enable &&
                x.SiteId == user.ObjEmployee.SiteId)
    .ToList();

查询是

SELECT `p`.`Id`, `p`.`Abrio`, `p`.`CajaMovementId`, `p`.`CajaStateId`, `p`.`Description`, `p`.`Enable`, `p`.`SiteId`, `s`.`Id`, `s`.`Address`, `s`.`CityId`, `s`.`Email`, `s`.`Enable`, `s`.`Name`, `s`.`Phone`, `c`.`Id`, `c`.`Description`, `c`.`Discriminator`
FROM `puestocajas` AS `p`
INNER JOIN `sites` AS `s` ON `p`.`SiteId` = `s`.`Id`
INNER JOIN `cajastate` AS `c` ON `p`.`CajaStateId` = `c`.`Id`
WHERE `p`.`Enable` AND (`p`.`SiteId` = 7);

我从 Visual Studio 输出窗口复制,当我直接在 MySQL 中执行此操作时的结果是 // 注意 CajaStateId 和 ObjCajaState 不匹配,我不知道为什么会发生这种情况。

ID 阿布里奥 CajaMovementId CajaStateId 描述 使能够 站点 ID ID 地址 城市编号 电子邮件 使能够 姓名 电话 ID 描述 鉴别器
'4' '员工1' '4' '1' '普埃斯托 2' '1' '7' '7' '地址1 ' '900014' 'examplemail@gmail.com' '1' “圣米格尔” '03811234567' '1' '阿比尔塔' 'CajaOpen'

在我的应用程序中,结果如下:

In my app the result is the following: 
puestocajas [1]= {
    Abrio = "Employee1", 
    CajaMovementId=4,
    CajaMovements,
    CajaStateId = 1,
    Description = Puesto 2,
    Enable = true,
    Id=4,
    **ObjCajaState {
        Description = "Cerrada",
        Id= 2
    }**,
    ObjSite,
    SiteId
}
public class PuestoCaja
{
    public int Id 
    public string Description 
    public Site ObjSite 
    public int SiteId 
    public bool Enable 
    public CajaState ObjCajaState 
    public List<CajaMovement> CajaMovements 
    public int? CajaMovementId 
    public int CajaStateId 
    public string Abrio 
}

public abstract class CajaState
{
    public int Id {get; set;}
    public string Description {get; set;}
}

public class CajaOpened : CajaState
{
    public CajaOpened()
    {
        this.Id = 1;
        this.Description = "Abierta";
    }
}

public class CajaClosed : CajaState
{
    public CajaClosed()
    {
        this.Id = 2;
        this.Description = "Cerrada";
    }
}
4

2 回答 2

0

不知何故,Pomelo Entity Framework Core 没有映射导航属性。我必须在模型构建器中配置它们,它就是这样工作的。

于 2021-06-08T14:04:37.147 回答
0

您的模型有点混乱,这就是为什么 EF Core 约定在涉及到您的导航属性及其对应的外键时会变得混乱。

查看以下示例代码,它显示了代码和模型的完整工作修复版本:

using System;
using System.Diagnostics;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;

namespace IssueConsoleTemplate
{
    public class BoxSite
    {
        public int Id { get; set; }
        public string Description { get; set; }
        public bool Enabled { get; set; }

        public int SiteId { get; set; }
        public BoxState State { get; set; }
        public int? BoxMovementId { get; set; }

        public Site ObjSite { get; set; }
        public BoxState ObjBoxState { get; set; }
        public BoxMovement ObjBoxMovement { get; set; }
    }

    public class Site
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Address { get; set; }
        public string Phone { get; set; }
        public string Email { get; set; }
        public bool Enabled { get; set; }
        
        public int CityId { get; set; }
        
        public City ObjCity { get; set; }
    }

    public class BoxMovement
    {
        public int Id { get; set; }

        public int DestinationSiteId { get; set; }
        
        public Site DestinationSite { get; set; }
    }

    public class City
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }

    public enum BoxState
    {
        Opened = 1,
        Closed = 2,
    }

    public class Context : DbContext
    {
        public DbSet<BoxSite> BoxSites { get; set; }
        public DbSet<Site> Sites { get; set; }
        public DbSet<City> Cities { get; set; }
        public DbSet<BoxMovement> BoxMovements { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            if (!optionsBuilder.IsConfigured)
            {
                var connectionString = "server=127.0.0.1;port=3306;user=root;password=;database=So67874766";
                var serverVersion = ServerVersion.AutoDetect(connectionString);
                optionsBuilder.UseMySql(
                        connectionString,
                        serverVersion,
                        options => options.CommandTimeout((int) TimeSpan.FromMinutes(2).TotalSeconds))
                    .UseLoggerFactory(
                        LoggerFactory.Create(
                            configure => configure
                                .AddConsole()
                                .AddFilter(level => level >= LogLevel.Information)))
                    .EnableSensitiveDataLogging()
                    .EnableDetailedErrors();
            }
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            //
            // Sample data:
            //
            
            modelBuilder.Entity<City>()
                .HasData(
                    new City {Id = 100, Name = "Paris"},
                    new City {Id = 200, Name = "Berlin"},
                    new City {Id = 300, Name = "New York"});

            modelBuilder.Entity<Site>()
                .HasData(
                    new Site {Id = 10, Name = "Paris Warehouse", Enabled = true, CityId = 100},
                    new Site {Id = 20, Name = "Berlin Warehouse", Enabled = true, CityId = 200},
                    new Site {Id = 30, Name = "New York Warehouse", Enabled = false, CityId = 300});

            modelBuilder.Entity<BoxSite>()
                .HasData(
                    new BoxSite
                    {
                        Id = 1,
                        Description = "Opened Vanilla Ice Cream Box in Paris",
                        Enabled = true,
                        SiteId = 10,
                        State = BoxState.Opened,
                    },
                    new BoxSite
                    {
                        Id = 2,
                        Description = "Closed Chocolate Ice Cream Box in Berlin",
                        Enabled = true,
                        SiteId = 20,
                        State = BoxState.Closed,
                    },
                    new BoxSite
                    {
                        Id = 3,
                        Description = "Closed Matcha Ice Cream Box New York",
                        Enabled = true,
                        SiteId = 30,
                        State = BoxState.Closed,
                    });
        }
    }

    internal static class Program
    {
        private static void Main()
        {
            using var context = new Context();

            context.Database.EnsureDeleted();
            context.Database.EnsureCreated();

            var berlinWarehouseSiteId = 20;

            var boxesInBerlin = context.BoxSites
                .Include(b => b.ObjSite)
                .Where(b => b.Enabled &&
                            b.SiteId == berlinWarehouseSiteId)
                .ToList();
            
            Trace.Assert(boxesInBerlin.Count == 1);
            Trace.Assert(boxesInBerlin[0].Description == "Closed Chocolate Ice Cream Box in Berlin");
        }
    }
}

它生成一个如下所示的数据库:

CREATE DATABASE `So67874766`;
ALTER DATABASE CHARACTER SET utf8mb4;

CREATE TABLE `Cities` (
    `Id` int NOT NULL AUTO_INCREMENT,
    `Name` longtext CHARACTER SET utf8mb4 NULL,
    CONSTRAINT `PK_Cities` PRIMARY KEY (`Id`)
) CHARACTER SET utf8mb4;

CREATE TABLE `Sites` (
    `Id` int NOT NULL AUTO_INCREMENT,
    `Name` longtext CHARACTER SET utf8mb4 NULL,
    `Address` longtext CHARACTER SET utf8mb4 NULL,
    `Phone` longtext CHARACTER SET utf8mb4 NULL,
    `Email` longtext CHARACTER SET utf8mb4 NULL,
    `Enabled` tinyint(1) NOT NULL,
    `CityId` int NOT NULL,
    CONSTRAINT `PK_Sites` PRIMARY KEY (`Id`),
    CONSTRAINT `FK_Sites_Cities_CityId` FOREIGN KEY (`CityId`) REFERENCES `Cities` (`Id`) ON DELETE CASCADE
) CHARACTER SET utf8mb4;

CREATE TABLE `BoxMovements` (
    `Id` int NOT NULL AUTO_INCREMENT,
    `DestinationSiteId` int NOT NULL,
    CONSTRAINT `PK_BoxMovements` PRIMARY KEY (`Id`),
    CONSTRAINT `FK_BoxMovements_Sites_DestinationSiteId` FOREIGN KEY (`DestinationSiteId`) REFERENCES `Sites` (`Id`) ON DELETE CASCADE
) CHARACTER SET utf8mb4;

CREATE TABLE `BoxSites` (
    `Id` int NOT NULL AUTO_INCREMENT,
    `Description` longtext CHARACTER SET utf8mb4 NULL,
    `Enabled` tinyint(1) NOT NULL,
    `SiteId` int NOT NULL,
    `State` int NOT NULL,
    `BoxMovementId` int NULL,
    `ObjBoxState` int NOT NULL,
    CONSTRAINT `PK_BoxSites` PRIMARY KEY (`Id`),
    CONSTRAINT `FK_BoxSites_BoxMovements_BoxMovementId` FOREIGN KEY (`BoxMovementId`) REFERENCES `BoxMovements` (`Id`) ON DELETE RESTRICT,
    CONSTRAINT `FK_BoxSites_Sites_SiteId` FOREIGN KEY (`SiteId`) REFERENCES `Sites` (`Id`) ON DELETE CASCADE
) CHARACTER SET utf8mb4;

INSERT INTO `Cities` (`Id`, `Name`)
VALUES (100, 'Paris');

INSERT INTO `Cities` (`Id`, `Name`)
VALUES (200, 'Berlin');

INSERT INTO `Cities` (`Id`, `Name`)
VALUES (300, 'New York');

INSERT INTO `Sites` (`Id`, `Address`, `CityId`, `Email`, `Enabled`, `Name`, `Phone`)
VALUES (10, NULL, 100, NULL, TRUE, 'Paris Warehouse', NULL);

INSERT INTO `Sites` (`Id`, `Address`, `CityId`, `Email`, `Enabled`, `Name`, `Phone`)
VALUES (20, NULL, 200, NULL, TRUE, 'Berlin Warehouse', NULL);

INSERT INTO `Sites` (`Id`, `Address`, `CityId`, `Email`, `Enabled`, `Name`, `Phone`)
VALUES (30, NULL, 300, NULL, FALSE, 'New York Warehouse', NULL);

INSERT INTO `BoxSites` (`Id`, `BoxMovementId`, `Description`, `Enabled`, `ObjBoxState`, `SiteId`, `State`)
VALUES (1, NULL, 'Opened Vanilla Ice Cream Box in Paris', TRUE, 0, 10, 1);

INSERT INTO `BoxSites` (`Id`, `BoxMovementId`, `Description`, `Enabled`, `ObjBoxState`, `SiteId`, `State`)
VALUES (2, NULL, 'Closed Chocolate Ice Cream Box in Berlin', TRUE, 0, 20, 2);

INSERT INTO `BoxSites` (`Id`, `BoxMovementId`, `Description`, `Enabled`, `ObjBoxState`, `SiteId`, `State`)
VALUES (3, NULL, 'Closed Matcha Ice Cream Box New York', TRUE, 0, 30, 2);

CREATE INDEX `IX_BoxMovements_DestinationSiteId` ON `BoxMovements` (`DestinationSiteId`);
CREATE INDEX `IX_BoxSites_BoxMovementId` ON `BoxSites` (`BoxMovementId`);
CREATE INDEX `IX_BoxSites_SiteId` ON `BoxSites` (`SiteId`);
CREATE INDEX `IX_Sites_CityId` ON `Sites` (`CityId`);

将为示例中的查询生成以下 SQL:

SELECT `b`.`Id`, `b`.`BoxMovementId`, `b`.`Description`, `b`.`Enabled`, `b`.`ObjBoxState`, `b`.`SiteId`, `b`.`State`, `s`.`Id`, `s`.`Address`, `s`.`CityId`, `s`.`Email`, `s
`.`Enabled`, `s`.`Name`, `s`.`Phone`
FROM `BoxSites` AS `b`
INNER JOIN `Sites` AS `s` ON `b`.`SiteId` = `s`.`Id`
WHERE `b`.`Enabled` AND (`b`.`SiteId` = @__berlinWarehouseSiteId_0)

简而言之,您正在对不应该使用的对象状态使用继承。您可以使用 anenum代替(如示例代码所示)。

于 2021-06-09T09:30:53.253 回答