我使用dapper进行这个工作 示例查询(实际上我使用的是真正的表):
async void Main()
{
var sql = @"SELECT PersonId = 1,
FirstName = 'john',
LastName = 'Lennon'";
using (var conn = new SqlConnection(@"Data Source=....;Initial Catalog=W...."))
{
var person = await conn.QueryAsync<Person>(sql);
person.Dump();
}
}
public class Person
{
public int PersonId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
结果:
因此映射按预期工作。但有时我会查询返回另一个值,如:
SELECT PersonId = 1,
FirstName = 'john',
LastName = 'Lennon' ,
cnt=(SELECT COUNT(1) FROM INFORMATION_SCHEMA.COLUMNS) //example
这是完全合法的:
题 :
是否可以返回Person
对象和其他非映射值(在同一个select
)
就像是 :
await conn.QueryAsync<Person,int>(sql)
一个真实的例子:
SELECT [AddressId]
,[PersonName]
,[Street]
,[Address_2]
,[House] ,
cnt=(COUNT(1) OVER (PARTITION BY house) )
FROM [WebERP].[dbo].[App_Address]
所以我返回一个带有count的Address
对象,该对象与同一个表有关,我不想要另一个select。
最简单的方法是将cnt添加到Person类中。你当然可以将它重命名为更有意义的东西。使它成为可为空的int,因此它将根据其在数据集中的存在而设置或不设置。
public class Person
{
public int PersonId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int? cnt { get;set; }
}
现在,这个cnt并不真正属于person类,但通常你不会将数据集分配给这样的类,你可以将它分配给类似DTO的东西,然后将它映射到你拥有的任何模型类或类中并使用你认为合适的额外属性。这将使您的业务类(例如Person)保持纯粹。
你确定你要这么做吗?正如歌曲所说,保持生活的阳光。 查询应该有返回类型。不同的查询应具有不同的返回类型。你说conn.Query<ReturnType>(SQL)
就是你conn.Query<ReturnType>(SQL)
在心上并承诺SQL将填充ReturnType。如果在一个地方,ReturnType具有查询永远不打算填充的字段,那对我来说就是代码气味。维护代码的人永远不会理解为什么会这样。如果稍后将来自不同查询的数据输入到单个方法中,请创建一个接口。
ORM思维的污染副作用是希望“规范化”你的课程。拥有数十个Person对象并不一定是一个问题,如果他们在不同的情况下做不同的事情。在您的数据库中,您不希望在两个地方使用相同的数据。在您的应用中,您不希望在两个地方使用相同的行为。这些是非常不同的概念。如果您使用的是QueryFirst (免责声明:我写的),这一切都会简单得多,而且您不必将手放在心上。