Dapper-Extensions
Dapper-Extensions copied to clipboard
Update byte[] fails
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");
}`
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
I have the same problem and i got it work like @swassberg solution's.
In the new version we'll have the possibility to assign DBType, Direction and other parameter options. It should solve this problem