我有以下课程:
public class Employee
{
private IEmployeeDataAccessor _employeeDataAccessor;
public Employee(IEmployeeDataAccessor emda )
{
_employeeDataAccessor = emda ;
}
public int UserId { get; private set; }
public string Username { get; set; }
}
IEmployeeDataAccessor
被添加到 startup.cs
中。
衣冠楚楚的我有:
return UserDb.Query<Employee>("sqlcmd for Selecting Employee here").SingleOrDefault();
我收到以下错误
'A parameterless default constructor or one matching signature is required'
不过,如果我的构造函数是无参数的,则没有问题。
有谁知道为什么吗?
我认为这个问题已经在几个评论和答案中得到了回答,但我会尝试将所有内容放在一起。
问题根源:Dapper 无法创建
Employee
类的对象,因为该类唯一的构造函数是 public Employee(IEmployeeDataAccessor emda)
,而 Dapper 不知道从哪里获取实现 IEmployeeDataAccessor
接口的对象。这并不奇怪,因为这不是表的列。 Dapper 是 SQL 结果到值对象的映射器。并且在此类值对象中不应该有任何额外的逻辑。
解决方案:问题来自糟糕的设计,你应该重构
Employee
类。它不应包含任何数据访问逻辑。它应该只是一个值类。您可以按照@Asherguru的建议进行操作,也可以将其实现为记录类:
public record Employee
(
int UserId,
string Username
);
然后
return UserDb.Query<Employee>("sqlcmd for Selecting Employee here").SingleOrDefault();
应该可以工作。
据我所知,这一行应该去实现
IEmployeeDataAccessor
的类,即这是一个获取Employee
值对象的数据访问逻辑。
我今天遇到了这个问题。 Dapper 不支持位置记录语法。
例如此代码不起作用:
public record MyMemati(string Name, string? Surname);
但是下面的代码可以工作:
public record MyMemati
{
public string Name { get; init; }
public string Surname { get; init; }
}
或者你必须添加默认的无参构造函数来记录如下
public record MyMemati(string Name, string? Surname)
{
public MyMemati():this(default, default)
{
}
}
员工是模范。所以你只能使用属性。不要添加任何其他内容。
删除
private IEmployeeDataAccessor _employeeDataAccessor;
public Employee(IEmployeeDataAccessor emda )
{
_employeeDataAccessor = emda ;
}
用这个代替:
public class Employee
{
public int UserId { get; private set; }
public string Username { get; set; }
}