Dapper-Extensions icon indicating copy to clipboard operation
Dapper-Extensions copied to clipboard

Update byte[] fails

Open KevinRaffay opened this issue 8 years ago • 3 comments

I have the classic Northwind DB and I am testing Dapper-Extensions CRUD code against the Categories table. It looks like the Update query is passing in a nvarchar for the Picture field instead of varbinary. Here are the differences between the Insert and Update statements send to SQL:

exec sp_executesql N'UPDATE [Categories] SET [Categories].[CategoryName] = @CategoryName, [Categories].[Description] = @Description, [Categories].[Picture] = @Picture WHERE ([Categories].[CategoryID] = @CategoryID_0)',N'@CategoryName nvarchar(4000), @Description nvarchar(4000),@Picture nvarchar(4000), @CategoryID_0 int',@CategoryName=N'TEST',@Description=N'UPDATED',@Picture=NULL,@CategoryID_0=161

exec sp_executesql N'INSERT INTO [Categories] ([Categories].[CategoryName], [Categories].[Description], [Categories].[Picture]) VALUES (@CategoryName, @Description, @Picture); SELECT CAST(SCOPE_IDENTITY() AS BIGINT) AS [Id]', N'@CategoryName nvarchar(4000), @Description nvarchar(4000), @Picture varbinary(8000)',@CategoryName=N'TEST',@Description=N'ff3e717f-4a6a-46e1-805f-77df67da6296',@Picture=NULL

Here is my POCO:

`public partial class Categories
{
    public int CategoryID { get; set; }

    public string CategoryName { get; set; }

    public string Description { get; set; }

    public byte[] Picture { get; set; }
}`

Here is the unit test that is failing:

    `[TestMethod]
    public void TestUpdateEntity()
    {
        var guid = Guid.NewGuid().ToString();

        var category = new Categories
        {
            CategoryName = "TEST",
            Description = guid

        };

        var id = _db.Insert(category);

        category = _db.Get<Categories>(id);
        category.Description = "UPDATED";

        _db.Update(category);

        Assert.IsTrue(((Categories)_db.Get<Categories>(id)).Description == "UPDATED");

    }`

KevinRaffay avatar Oct 18 '16 23:10 KevinRaffay

I got it to work after modifying the Source (DapperImplementor.cs):

 public bool Update<T>(IDbConnection connection, T entity, IDbTransaction transaction, int? commandTimeout) where T : class
{
.
.
.
foreach (var property in ReflectionHelper.GetObjectValues(entity).Where(property => columns.Any(c => c.Name == property.Key)))
            {
                    dynamicParameters.Add(property.Key, property.Value);
            }
.
.
.
}

To

foreach (var property in ReflectionHelper.GetObjectValues(entity).Where(property => columns.Any(c => c.Name == property.Key)))
            {
                if(entity?.GetType().GetProperties().FirstOrDefault(x => x.Name == property.Key)?.PropertyType == typeof(byte[]))
                    dynamicParameters.Add(property.Key, property.Value,DbType.Binary);
               else
                    dynamicParameters.Add(property.Key, property.Value);
            }

Code is not fully tested and is just a workaround

swassberg avatar Jan 30 '17 16:01 swassberg

I have the same problem and i got it work like @swassberg solution's.

questorkelvyn avatar Aug 29 '17 17:08 questorkelvyn

In the new version we'll have the possibility to assign DBType, Direction and other parameter options. It should solve this problem

valfrid-ly avatar May 07 '21 14:05 valfrid-ly