1

我正在使用 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>();

GetByIdSkipRepository像这样调用:

var skip = _skipRepository.GetById(skipId);

在我的表中,我只有 3 条记录,如您所见,我正在尝试获取Skipby Id

这是我的域对象:

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 个元素。

我的数据库表有 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);
        }
        ...
    }

仍然没有运气。

4

1 回答 1

0

[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)

我认为您的图层有问题,或者可能是上层版本有问题。

于 2022-01-21T09:53:20.650 回答