使用OrmLite填充POCO中的某些列时遇到一些困难。我有三张名为Dog,Bowl和DogBowl的桌子。 DogBowl是一个交叉表,拥有狗和碗的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属性?
答案 0 :(得分:4)
生成的SQL可能是正确的。您可以通过检查属性db.GetLastSql()来验证执行后生成的SQL。
问题在于将结果指定为
db.Select<DogBowl>
,您正在创建DogBowl对象列表。 DogBowl属性DogName和BowlColor将始终为null,因为SQL语句中没有与这些名称完全匹配的字段。 OrmLite不会神奇地弄清楚那里会发生什么 - 你必须让它们按名称匹配。
如果要将结果分配给包含Dog和Bowl字段的“flat”对象,可以定义新的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, });
答案 1 :(得分:2)
想要添加到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();
}