Hy,
I have post a question about CLR User-Defined Aggregates few month ago on this post.
This works great with int. But now I would like to do the same functions with a datetime parameter.
But I can't get work. Like this, the code won't work... The problem is on the read function who generate this error on sql server :
System.ArgumentOutOfRangeException: Les graduations doivent être comprises entre DateTime.MinValue.Ticks et DateTime.MaxValue.Ticks.
Nom du paramètre : ticks
System.ArgumentOutOfRangeException:
à System.DateTime..ctor(Int64 ticks)
à sMaxDatetime.Read(BinaryReader reader)
So I tried to convert my sql Datetime into ticks, with this, but it'not working eather. I have a OverflowException on the conversion to datetime.
I have found this post, and it's appear that I can't map my datetime to the BinaryReader...
So I running out of ideas to do my aggregate...
Have you a idea to do this ?
Here is the actual code :
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using System.Diagnostics.Eventing.Reader;
using System.Globalization;
using Microsoft.SqlServer.Server;
using System.Text;
using System.Collections;
using System.IO;
[Serializable]
[SqlUserDefinedAggregate(
Format.UserDefined,
IsInvariantToOrder = true,
IsInvariantToNulls = true,
IsInvariantToDuplicates = true,
MaxByteSize = -1)]
public struct sMaxDatetime : IBinarySerialize
{
#region Helpers
private struct MyData
{
public string Data { get; set; }
public DateTime? Group { get; set; }
public int CompareTo(MyData other)
{
if (Group == null)
return other.Group == null ? 0 : -1;
if (other.Group == null)
return 1;
return Group.Value.CompareTo(other.Group.Value);
}
public static bool operator < (MyData left, MyData right)
{
return left.CompareTo(right) == -1;
}
public static bool operator > (MyData left, MyData right)
{
return left.CompareTo(right) == 1;
}
}
#endregion
private MyData _maxItem;
public void Init()
{
_maxItem = default(MyData);
}
public void Accumulate(SqlString data, SqlDateTime group)
{
if (!data.IsNull && !group.IsNull)
{
var current = new MyData
{
Data = data.Value,
Group = group.Value,
};
if (current > _maxItem)
{
_maxItem = current;
}
}
}
public void Merge(sMaxDatetime other)
{
if (other._maxItem > _maxItem)
{
_maxItem = other._maxItem;
}
}
public SqlString Terminate()
{
return _maxItem.Data;
}
public void Read(BinaryReader reader)
{
//if (reader.ReadBoolean())
//{
_maxItem.Data = reader.ReadString();
_maxItem.Group = new DateTime(reader.ReadInt64());
//}
//else
//{
// _maxItem = default(MyData);
//}
}
public void Write(BinaryWriter writer)
{
if (_maxItem.Group.HasValue)
{
writer.Write(true);
writer.Write(_maxItem.Group.Value.ToString());
writer.Write(_maxItem.Data);
}
else
{
writer.Write(false);
}
}
}
PS : I have this related post with sql_variant unclosed who could do the tricks but I can't get to work eather.