为什么 DapperExtensions GetById 不返回对象?
Why DapperExtensions GetById not returning the object?
我正在使用 DapperExtensions,我使用的框架是 .NET-Core。
我有一个包含以下内容的基本存储库:
public abstract class TableRepository<T> : ITableRepository<T> where T : class
{
public T GetById(int id)
{
using (SqlConnection sqlConnection = new SqlConnection(_dbConnection.ConnectionString))
{
return sqlConnection.Get<T>(id);
}
}
....
}
ITableRepository
包含多个方法,但在这个特定场景中我们对GetById
方法感兴趣:
public interface ITableRepository<T>
{
T GetById(int id);
...
}
我有一个 ISkipRepository
接口,它继承自 ITableRepository
并且还定义了类型:
public interface ISkipRepository : ITableRepository<Skip>
{
Skip GetByName(string name);
bool Exists(int id, string name);
}
我有一个 ISkipRepository
的实例,如下所示:
public class SkipRepository : TableRepository<Skip>, ISkipRepository
{
public SkipRepository(IDbConnection dbConnection) : base(dbConnection) { }
public Skip GetByName(string name)
{
string sql = @"SELECT * FROM [Skip] WHERE [Name] = @name";
object parameters = new
{
name
};
return QuerySingle(sql, parameters, CommandType.Text);
}
public bool Exists(int id, string name)
{
var group = new PredicateGroup { Operator = GroupOperator.And, Predicates = new List<IPredicate>() };
group.Predicates.Add(Predicates.Field<Skip>(s => s.Id, Operator.Eq, id, true));
group.Predicates.Add(Predicates.Field<Skip>(s => s.Name, Operator.Eq, name));
return Exists(group);
}
}
我已经在我的 Startup
:
中注册了这个实例
services.AddTransient<ISkipRepository, SkipRepository>();
然后像这样在 SkipRepository
上调用 GetById
:
var skip = _skipRepository.GetById(skipId);
在我的 table 中,我只有 3 条记录,如您所见,我正试图通过 Id
获取 Skip
。
这是我的域对象:
public class Skip
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public decimal BasePrice { get; set; }
public decimal PricePerDayAfter14Days { get; set; }
public int Quantity { get; set; }
}
这是我的 Skip
:
的一个小巧的映射器 class
public sealed class SkipMapper : ClassMapper<Skip>
{
public SkipMapper()
{
Schema("dbo");
Table("Skip");
Map(x => x.Id).Key(KeyType.Identity);
AutoMap();
}
}
出于某种原因,GetById
抛出一个异常,表明它需要 1 个元素但得到了 3 个元素。
我的数据库 table 有 3 条记录,所以我开始更深入地挖掘 运行 一个 SQL Profiler 到我发现这个查询的内容:
SELECT [y_1].[Id] AS [c_0], [y_1].[Name] AS [c_1], [y_1].[Description] AS [c_2], [y_1].[BasePrice] AS [c_3], [y_1].[PricePerDayAfter14Days] AS [c_4], [y_1].[Quantity] AS [c_5] FROM [Skip] [y_1]
如您所见,它没有添加 WHERE
子句,我很难理解为什么。
有人知道我做错了什么吗?
更新:
我删除了所有图层并直接在我的控制器中完成了此操作:
[HttpGet("{id}")]
public IActionResult Index(int id)
{
using (SqlConnection conn = new SqlConnection("Server=localhost;Database=develop;Trusted_Connection=True;MultipleActiveResultSets=true"))
{
Data.Models.Skip skipModel = conn.Get<Data.Models.Skip>(1);
}
...
}
仍然没有运气。
您正在使用 [Key]
属性映射主键。此映射不适用于 Dapper Extensions;它目前正在获取基于约定的映射(名为 Id
的 属性)。只是为了确定,请像下面这样明确映射:
public sealed class ProductMapper : ClassMapper<Product>
{
public ProductMapper()
{
Schema("dbo");
Table("Products");
Map(x => x.Id).Key(KeyType.Guid);
AutoMap();
}
}
您还需要在项目启动时调用 SetMappingAssemblies
以应用这些映射。
另外,在 SetMappingAssemblies
之后的启动时设置方言,如下所示:
DapperExtensions.DapperExtensions.SqlDialect = new DapperExtensions.Sql.SqlServerDialect();
请参阅 答案以了解有关 Dapper Extensions 中映射的更多信息。
我复制了下面的代码并在我的系统上执行了。
小巧玲珑:1.50.4.0.
DapperExtensions:1.6.3.0.
目标 .NET 框架:4.6.1;不是核心。
DapperExtensions.DapperExtensions.SetMappingAssemblies(new[] { Assembly.GetExecutingAssembly() });
DapperExtensions.DapperExtensions.SqlDialect = new DapperExtensions.Sql.SqlServerDialect();
using(SqlConnection conn = new SqlConnection(connString))
{
Skip skip = conn.Get<Skip>(1);
}
public class Skip
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public decimal BasePrice { get; set; }
public decimal PricePerDayAfter14Days { get; set; }
public int Quantity { get; set; }
}
public sealed class SkipMapper : ClassMapper<Skip>
{
public SkipMapper()
{
Schema("dbo");
Table("Skip");
Map(x => x.Id).Key(KeyType.Identity);
AutoMap();
}
}
这会生成以下 SQL 正确的查询。
SELECT [dbo].[Skip].[Id], [dbo].[Skip].[Name], [dbo].[Skip].[Description], [dbo].[Skip].[BasePrice], [dbo].[Skip].[PricePerDayAfter14Days], [dbo].[Skip].[Quantity] FROM [dbo].[Skip] WHERE ([dbo].[Skip].[Id] = @Id_0)
我认为你的层有问题,或者可能是更高版本有问题。
我正在使用 DapperExtensions,我使用的框架是 .NET-Core。
我有一个包含以下内容的基本存储库:
public abstract class TableRepository<T> : ITableRepository<T> where T : class
{
public T GetById(int id)
{
using (SqlConnection sqlConnection = new SqlConnection(_dbConnection.ConnectionString))
{
return sqlConnection.Get<T>(id);
}
}
....
}
ITableRepository
包含多个方法,但在这个特定场景中我们对GetById
方法感兴趣:
public interface ITableRepository<T>
{
T GetById(int id);
...
}
我有一个 ISkipRepository
接口,它继承自 ITableRepository
并且还定义了类型:
public interface ISkipRepository : ITableRepository<Skip>
{
Skip GetByName(string name);
bool Exists(int id, string name);
}
我有一个 ISkipRepository
的实例,如下所示:
public class SkipRepository : TableRepository<Skip>, ISkipRepository
{
public SkipRepository(IDbConnection dbConnection) : base(dbConnection) { }
public Skip GetByName(string name)
{
string sql = @"SELECT * FROM [Skip] WHERE [Name] = @name";
object parameters = new
{
name
};
return QuerySingle(sql, parameters, CommandType.Text);
}
public bool Exists(int id, string name)
{
var group = new PredicateGroup { Operator = GroupOperator.And, Predicates = new List<IPredicate>() };
group.Predicates.Add(Predicates.Field<Skip>(s => s.Id, Operator.Eq, id, true));
group.Predicates.Add(Predicates.Field<Skip>(s => s.Name, Operator.Eq, name));
return Exists(group);
}
}
我已经在我的 Startup
:
services.AddTransient<ISkipRepository, SkipRepository>();
然后像这样在 SkipRepository
上调用 GetById
:
var skip = _skipRepository.GetById(skipId);
在我的 table 中,我只有 3 条记录,如您所见,我正试图通过 Id
获取 Skip
。
这是我的域对象:
public class Skip
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public decimal BasePrice { get; set; }
public decimal PricePerDayAfter14Days { get; set; }
public int Quantity { get; set; }
}
这是我的 Skip
:
public sealed class SkipMapper : ClassMapper<Skip>
{
public SkipMapper()
{
Schema("dbo");
Table("Skip");
Map(x => x.Id).Key(KeyType.Identity);
AutoMap();
}
}
出于某种原因,GetById
抛出一个异常,表明它需要 1 个元素但得到了 3 个元素。
我的数据库 table 有 3 条记录,所以我开始更深入地挖掘 运行 一个 SQL Profiler 到我发现这个查询的内容:
SELECT [y_1].[Id] AS [c_0], [y_1].[Name] AS [c_1], [y_1].[Description] AS [c_2], [y_1].[BasePrice] AS [c_3], [y_1].[PricePerDayAfter14Days] AS [c_4], [y_1].[Quantity] AS [c_5] FROM [Skip] [y_1]
如您所见,它没有添加 WHERE
子句,我很难理解为什么。
有人知道我做错了什么吗?
更新:
我删除了所有图层并直接在我的控制器中完成了此操作:
[HttpGet("{id}")]
public IActionResult Index(int id)
{
using (SqlConnection conn = new SqlConnection("Server=localhost;Database=develop;Trusted_Connection=True;MultipleActiveResultSets=true"))
{
Data.Models.Skip skipModel = conn.Get<Data.Models.Skip>(1);
}
...
}
仍然没有运气。
您正在使用 [Key]
属性映射主键。此映射不适用于 Dapper Extensions;它目前正在获取基于约定的映射(名为 Id
的 属性)。只是为了确定,请像下面这样明确映射:
public sealed class ProductMapper : ClassMapper<Product>
{
public ProductMapper()
{
Schema("dbo");
Table("Products");
Map(x => x.Id).Key(KeyType.Guid);
AutoMap();
}
}
您还需要在项目启动时调用 SetMappingAssemblies
以应用这些映射。
另外,在 SetMappingAssemblies
之后的启动时设置方言,如下所示:
DapperExtensions.DapperExtensions.SqlDialect = new DapperExtensions.Sql.SqlServerDialect();
请参阅
我复制了下面的代码并在我的系统上执行了。
小巧玲珑:1.50.4.0.
DapperExtensions:1.6.3.0.
目标 .NET 框架:4.6.1;不是核心。
DapperExtensions.DapperExtensions.SetMappingAssemblies(new[] { Assembly.GetExecutingAssembly() });
DapperExtensions.DapperExtensions.SqlDialect = new DapperExtensions.Sql.SqlServerDialect();
using(SqlConnection conn = new SqlConnection(connString))
{
Skip skip = conn.Get<Skip>(1);
}
public class Skip
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public decimal BasePrice { get; set; }
public decimal PricePerDayAfter14Days { get; set; }
public int Quantity { get; set; }
}
public sealed class SkipMapper : ClassMapper<Skip>
{
public SkipMapper()
{
Schema("dbo");
Table("Skip");
Map(x => x.Id).Key(KeyType.Identity);
AutoMap();
}
}
这会生成以下 SQL 正确的查询。
SELECT [dbo].[Skip].[Id], [dbo].[Skip].[Name], [dbo].[Skip].[Description], [dbo].[Skip].[BasePrice], [dbo].[Skip].[PricePerDayAfter14Days], [dbo].[Skip].[Quantity] FROM [dbo].[Skip] WHERE ([dbo].[Skip].[Id] = @Id_0)
我认为你的层有问题,或者可能是更高版本有问题。