OrmLite在联接的表中选择多列
本文关键字:选择 OrmLite | 更新日期: 2023-09-27 18:27:10
我在使用OrmLite填充POCO中的某些列时遇到了一些困难。我有三张桌子,分别叫Dog、Bowl和DogBowl。DogBowl是一张连接桌,上面有Dog和Bowl的id。
Dogs
PK Id: int, not null
Breed: varchar(20), not null
Name: varchar(20), not null
Bowls
PK Id: int, not null
Type: varchar(20), not null
Color: varchar(20), not null
Dogs_Bowls
PK: DogId, not null
PK: BowlId, not null
以下是我绘制的POCO
public class Dog : IHasId<int>
{
[AutoIncrement]
public int Id { get; set; }
[Required]
public string Breed { get; set; }
[Required]
public string Name { get; set; }
}
public class Bowl : IHasId<int>
{
[AutoIncrement]
public int Id { get; set; }
[Required]
public string Type { get; set; }
[Required]
public string Color { get; set; }
}
public class DogBowl
{
[Required]
public int DogId { get; set; }
[Required]
public int BowlId { get; set; }
[Ignore]
public string DogName { get;set; }
[Ignore]
public string BowlColor { get;set; }
}
这是我正在运行的c#代码。
var dogBowl = db.Select<DogBowl>(db
.From<Dog>()
.Join<Dog, DogBowl>((d, db) => d.Id == db.DogId)
.Join<DogBowl, Bowl>((db, b) => db.BowlId == b.Id)
.Where<Dog>(d => d.Id == 5))
.ToList();
我想生成的SQL是这样的:
select
db.DogId,
db.BowlId,
d.Name AS DogName,
b.Color as BowlColor
from DogBowl db
join dog d on db.DogId = d.Id
join bowl b on db.BowlId = b.Id
where d.Id = 5
我的问题是DogBowl.DogName和DogBowl.BowlColor属性在代码执行后为null。我正在使用上提供的说明https://github.com/ServiceStack/ServiceStack.OrmLite从标题为"在联接的表中选择多个列"的部分,但它不起作用。如何填充DogBowl.DogName和DogBowl.BowlColor属性?
生成的SQL可能是正确的。您可以通过检查属性db来验证执行后生成的SQL。GetLastSql()。
问题是通过将结果指定为
db.Select<DogBowl>
,您正在创建DogBowl对象的列表。DogBowl属性DogName和BowlColor将始终为null,因为SQL语句中没有与这些名称完全匹配的字段。OrmLite不会神奇地弄清楚那里发生了什么——你必须让它们按名称匹配。
如果您想将结果分配给一个包含Dog和Bowl字段的"平面"对象,您可以定义一个新的DTO并分配结果,如下所示:
public class FullDogBowl
{
public int DogId { get; set; }
public int BowlId { get; set; }
public string Breed { get; set; }
public string Name { get; set; }
public string Type { get; set; }
public string Color { get; set; }
}
var dogBowl = db.Select<FullDogBowl>(db
.From<Dog>()
.Join<Dog, DogBowl>((d, db) => d.Id == db.DogId)
.Join<DogBowl, Bowl>((db, b) => db.BowlId == b.Id)
.Where<Dog>(d => d.Id == 5))
.ToList();
或者,如果您确切地知道要使用的SQL,只需使用它:
string sql = @"select
db.DogId,
db.BowlId,
d.Name AS DogName,
b.Color as BowlColor
from DogBowl db
join dog d on db.DogId = d.Id
join bowl b on db.BowlId = b.Id
where d.Id = @dog_id ";
var dogBowlList = db.SqlList<DogBowl>(sql, new { dog_id = 5, });
想在Raul的回答中添加[Ignore]
告诉OrmLite完全忽略该属性,这样您将表重新用作合并的POCO"视图"的方法就不会起作用。我建议将结果集POCO拆分为一个单独的POCO,其中包含您想要返回的所有字段:
public class DogBowl
{
[Required]
public int DogId { get; set; }
[Required]
public int BowlId { get; set; }
}
public class DogBowlInfo
{
public int DogId { get; set; }
public int BowlId { get; set; }
public string DogName { get; set; }
public string BowlColor { get; set; }
}
它现在返回一个填充的结果集,其中包含:
using (var db = OpenDbConnection())
{
db.DropAndCreateTable<Dog>();
db.DropAndCreateTable<Bowl>();
db.DropAndCreateTable<DogBowl>();
var dog = new Dog { Breed = "Breed", Name = "Name" };
var bowl = new Bowl { Color = "Color", Type = "Type" };
db.Save(dog);
db.Save(bowl);
db.Insert(new DogBowl { DogId = dog.Id, BowlId = bowl.Id });
var dogBowl = db.Select<DogBowlInfo>(
db.From<Dog>()
.Join<Dog, DogBowl>((d, b) => d.Id == b.DogId)
.Join<DogBowl, Bowl>((d, b) => d.BowlId == b.Id)
.Where<Dog>(d => d.Id == dog.Id));
dogBowl.PrintDump();
}