gpt4 book ai didi

C# Automapper IQueryable - LINQ 2 SQLite - 查询仅返回父项,嵌套子项始终为 null

转载 作者:行者123 更新时间:2023-12-04 04:15:02 26 4
gpt4 key购买 nike

互联网的 friend 们好,

我已经在 SO 上搜索了几天,尝试了很多可能的解决方案,但我无法在以下测试项目中解决我的问题。 请原谅我的技能不足,因为我是一名自学成才的程序员,现在才一年多,这是我关于 SO 的第一个问题。

情况:我有 2 个实体类 CarWheel并希望使用 c# 的 linq to sql(ite) 从单个数据库表中存储和查询它们。

    public class Car
{
public Int64? Id { get; private set; }
public string Manufacturer { get; private set; } = "Porsche";
public double Mileage { get; private set; }
public Wheel Wheel { get; private set; }

public Car()
{
this.Id = Program.CarCount;
Mileage = new System.Random(Program.CarCount).Next(0, 500000);

Program.CarCount++;
}

public Car CreateWheels()
{
// Adds Wheel 2 Car
}
}

public class Wheel
{
public Int64? Id { get; set; }
public string Manufacturer { get; set; } = "Continental";

public Wheel() { Id = Program.WheelCount; }
}

不幸的是,因为它是我正在处理的另一个项目的测试项目,所以我无法将原始数据拆分成多个 OR 表。

为了使用单个表格,我将它们展平为单个 CarDto与我的单个数据库表匹配的类。我将这两个类扁平化为 CarDto与使用 AutoMap 的 LINQ 2 SQLite 一起使用并分配各个数据库列。

    [Table(Name = "Cars")]
[AutoMap(typeof(Car), ReverseMap = true)]
public class CarDto
{
public CarDto(){ }

[Column(IsPrimaryKey = true)]
public Int64? Id { get; set; }
[Column]
public string Manufacturer { get; set; }
[Column]
public double Mileage { get; set; }
[Column]
public Int64? WheelId { get; set; }
[Column]
public string WheelManufacturer { get; set; }
}

DTO 类和实体类之间的映射是使用映射器完成的 CarMapper使用 AutoMapper v.9x

    public class CarMapper
{
public IMapper Map => Config.CreateMapper();
IConfigurationProvider Config;

public CarMapper()
{
Config = new MapperConfiguration(cfg =>
{
cfg.AddMaps(typeof(CarMapper).Assembly);
});
Config.AssertConfigurationIsValid();
}
}

与数据库的交互是通过存储库类处理的 CarRepo包含映射器和 DataContext C# Linq2SQL类

    public class CarContext : DataContext
{
public Table<CarDto> CarDtos;
public CarContext(IDbConnection connection) : base(connection) { }
}

public class CarRepo
{
private string conn;
CarMapper mp = new CarMapper();
CarContext CarContext => new CarContext(new SQLiteConnection(conn));
public IQueryable<Car> Cars { get => Qry(); }

public CarRepo(string connectionString) { this.conn = connectionString; }

private IQueryable<Car> Qry()
{
return mp.Map.ProjectTo<Car>(CarContext.CarDtos);
}

public List<Car> GetAllCarsFromDb()
{
var dtosFromDb = new List<CarDto>();
using (var db = CarContext)
return mp.Map.Map<List<CarDto>, List<Car>>(db.CarDtos.ToList());
}

public void InsertCars(List<Car> cars)
{
using (var db = CarContext)
{
db.CarDtos.InsertAllOnSubmit(mp.Map.Map<List<Car>, List<CarDto>>(cars));
db.SubmitChanges();
}
}
}

问题:

插入和映射 CarDto -表到Car工作完美。正在运行 repo.Cars.Where(car => car.Id <= 5).ToList();除嵌套对象外的预期结果 Wheel ,它始终返回 null。投影汽车查询时存在问题,可能在于查询表达式的映射。查看生成的查询,这似乎很明显。

SELECT[t0].[Id], [t0].[Manufacturer], [t0].[Mileage]
FROM[Cars] AS[t0]
WHERE[t0].[Id] <= @p0

运行以下映射 mp.Map.Map<List<CarDto>, List<Car>>(db.CarDtos.ToList());工作并交付 Car包括 Wheel实例。

我尝试了很多解决方案(自定义映射,...)并浏览了 AutoMapper 文档,但无法解决我的问题。希望可以有人帮帮我。

来自德国的欢呼!亨里克

编辑:附言我添加了一个要点 https://gitlab.com/snippets/1957648 https://gist.github.com/henrikherr/29eb2913d403ab1d6bede52ed011869a

最佳答案

正如@LucianBargaoanu 指出的那样,ProjectTo 不适用于ForPath。他还正确地指出我的 dto 和实体的逻辑/用法是相反的。

此外,如果我的数据库设计与我的 CarWheel 类在更相关的类/对象中相匹配,我就不必执行可查询映射方式或者我的 repo 协议(protocol)是否会公开和处理 dto 类。

You're relying implicitly on ForPath here and that doesn't work with ProjectTo. But you entities/dtos are exactly reversed. Car should be in the DB, with a Wheel FK entity. And CarDto would show up in the UI, or whatever uses the DB. – Lucian Bargaoanu

关于C# Automapper IQueryable - LINQ 2 SQLite - 查询仅返回父项,嵌套子项始终为 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60873396/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com