[英]Entity Framework Core 5.0 is not mapping well the mysql query
我正在将 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 output window 复制了结果,当我直接在 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";
}
}
不知何故,Pomelo Entity Framework Core 没有 map 导航属性。 我必须在 model 构建器中配置它们,它就是这样工作的。
您的 model 有点混乱,这就是为什么 EF Core 约定在您的导航属性及其相应的外键方面变得混乱的原因。
查看以下示例代码,它显示了您的代码和 model 的完整工作修复版本:
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)
简而言之,您将 inheritance 用于 object 状态,而您不应该这样做。 您可以改用enum
(如示例代码所示)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.