henkmollema / Dommel

CRUD operations with Dapper made simple.
MIT License
634 stars 100 forks source link

Update method with Date object #250

Closed DanieleSky closed 3 years ago

DanieleSky commented 3 years ago

Hi, I need to save in my SQL Server database a column with only date part of DateTime. I created a struct like this:

public struct Date {
  private DateTime? date;

  public DateTime? Value { get => date; set => date = value?.Date; }
  public Date(DateTime date) { this.date = new DateTime(); this.Value = date; }

  public static explicit operator Date(DateTime date) => new Date(date);
  public static implicit operator DateTime?(Date d) => d.Value;
}

used in:

public class Profile 
{
   public string UserName { get; set; }
   public Date LastLoginDate { get; set; }
}

and mapped like this:

public class ProfileMap : DommelEntityMap<Profile>
  {
    public ProfileMap()
    {
       ToTable("Profiles");
       Map(u => u.UserName).ToColumn("UserName");
       Map(u => u.LastLoginDate).ToColumn("LastLoginDate");
    }
  }

With Get method I can obtain the column value thanks the conversion operators. But when I try to update a entity, the SQL generated don't have the LastLoginDate field.

Using Dapper directly all works thanks the AddTypeMap and implementing IConvertible interface

SqlMapper.AddTypeMap(typeof(Date), DbType.DateTime);

for example:

SqlMapper.AddTypeMap(typeof(Date), DbType.DateTime);
var profile = SqlMapperExtensions.Get<Profile>(Connection, id, Transaction);
profile.LastLoginDate= new Date(DateTime.Now.AddDays(100));
SqlMapperExtensions.Update(Connection, profile, Transaction);

How I can do this with Dommel? Thanks

henkmollema commented 3 years ago

You can create your own implementation of IPropertyResolver to achieve this. For example, extend the DefaultPropertyResolver implementation and override protected virtual HashSet<Type> PrimitiveType. Then register your implementation with DommelMapper.SetPropertyResolver() at application startup.

https://github.com/henkmollema/Dommel/blob/master/src/Dommel/DefaultPropertyResolver.cs#L47

DanieleSky commented 3 years ago

Thanks, works perfectly. For others, this is my implementation:

public class MyPropertyResolver : DefaultPropertyResolver
    {
        protected override HashSet<Type> PrimitiveTypes
        {
            get
            {
                //add Date type like primitive for Dommel
                base.PrimitiveTypes.Add(typeof(Date));
                //add the type map for Dapper
                SqlMapper.AddTypeMap(typeof(Date), DbType.DateTime);
                return base.PrimitiveTypes;
            }
        }
    }