Попробуйте этот код. ВАШ код не работает, потому что компилятор переписывает Ваши неявные делегаты Func скомпилированным делегатам (я настоятельно рекомендую использовать отражатель, чтобы проверить это своими глазами). Это было бы неплохо, поскольку это в основном по соображениям производительности (чтобы избежать компиляции каждый раз, когда это вызывается), но, к сожалению, это создает поле, которое не сериализуемо и просто не работает с SQL Server. Чтобы избежать этого, вам нужно использовать выражения и компилировать их вручную. Моя реализация создает делегатов только один раз за весь вызов (init).
В общем, я бы настоятельно рекомендовал реализовать режим с использованием коллекции HashSet с какой-то группировкой или, возможно, даже с SortedHashSet.
[Microsoft.SqlServer.Server.SqlUserDefinedAggregate(Format.UserDefined, MaxByteSize = 8000, IsInvariantToOrder=true, IsNullIfEmpty=true, IsInvariantToNulls=true)]
public struct Mode : IBinarySerialize
{
public void Init()
{
placeholder = new List<int>(10000);
Expression<Func<int, int>> ass = p => p;
grouper = ass.Compile();
Expression<Func<IGrouping<int, int>,int>> ass2 = q => q.Count();
sorter = ass2.Compile();
}
public void Accumulate(SqlInt32 Value)
{
placeholder.Add(Value.Value);
}
public void Merge(Mode Group)
{
placeholder.AddRange(Group.placeholder);
}
public SqlInt32 Terminate()
{
SqlInt32 result = placeholder.GroupBy(grouper).OrderByDescending(sorter).FirstOrDefault().Key ?? null;
placeholder.Clear();
return result;
}
// This is a place-holder member field
private List<int> placeholder;
private Func <int, int> grouper;
private Func<IGrouping<int, int>, int> sorter;
//IBinarySerialize
public void Read(BinaryReader r)
{
int itemCount = r.ReadInt32();
this.placeholder = new List<int>(itemCount);
for (int i = 0; i <= itemCount - 1; i++)
{
this.placeholder.Add(r.ReadInt16());
}
}
//IBinarySerialize
public void Write(BinaryWriter w)
{
w.Write(this.placeholder.Count);
foreach (Int32 s in this.placeholder)
{
w.Write(s);
}
}
}