假设我正在使用 Dapper 运行标准选择查询以使用存储过程填充对象。
public IEnumerable<Person> GetPeople()
{
IEnumerable<Person> people;
using (var con = new SqlConnection(connectionString))
{
people = con.Query<Person>("[dbo].[sp_Select_People]", commandType: CommandType.StoredProcedure);
}
return people;
}
人类定义为:
public class Person
{
public string Name{ get; set; }
public string Age{ get; set; }
public string Date { get; set; }
public string Error{ get; set; }
假设被调用的存储过程是
SELECT Age, Date, Error, Name FROM ...
Dapper 将以何种顺序填充类对象:
从使用断点的个人测试来看,答案似乎是随机的或一些我无法弄清楚的未知优化方案。这是可配置的吗?
我对理论问题更感兴趣,但是对于上下文,提示这个问题的“为什么”是确定最后填充哪个以便根据其他成员的值设置错误属性:
private string _date/_age/_name/etc; <---- whichever property is populated last
public string Date/Age/Name
{
get { return _date; }
set
{
_date = value;
SetError();
}
}
private void SetError()
{
//if (Name == something && Age == something) Error = "x"
//if (etc...
}
Dapper 按从左到右的顺序处理列,与
CommandBehavior.SequentialAccess
的规则一致——并立即存储值。所以:查询列顺序。
如果存在映射到查询的自定义构造函数,事情会变得little更复杂,但是,a:只有一点点,b:这里不适用。
正如其他人所说,这不是正确的方法。但是,如果顺序真的是随机的并且您没有其他选择,您可以对映射字段进行计数并且仅在它们全部映射后才进行验证
public class Person
{
private int _setCount = 0;
private string _name;
private string _age;
public string Name
{
get { return _name; }
set
{
_name = value;
_setCount++;
SetError();
}
}
public string Age
{
get { return _age; }
set
{
_age = value;
_setCount++;
SetError();
}
}
private void SetError()
{
if (_setCount != MaxNumberOfProperties) return;
//if (Name == something && Age == something) Error = "x"
//if (etc...
}
}
如您所见,它变得很难维护。