Вы можете использовать этот контейнер ScalarCollection
, который ограничивает массив и предоставляет некоторые параметры манипуляции ( Gist ):
Использование:
public class Person
{
public int Id { get; set; }
//will be stored in database as single string.
public SaclarStringCollection Phones { get; set; } = new ScalarStringCollection();
}
Код:
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
namespace System.Collections.Specialized
{
#if NET462
[ComplexType]
#endif
public abstract class ScalarCollectionBase :
#if NET462
Collection,
#else
ObservableCollection
#endif
{
public virtual string Separator { get; } = "\n";
public virtual string ReplacementChar { get; } = " ";
public ScalarCollectionBase(params T[] values)
{
if (values != null)
foreach (var item in Items)
Items.Add(item);
}
#if NET462
[Browsable(false)]
#endif
[EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("Not to be used directly by user, use Items property instead.")]
public string Data
{
get
{
var data = Items.Select(item => Serialize(item)
.Replace(Separator, ReplacementChar.ToString()));
return string.Join(Separator, data.Where(s => s?.Length > 0));
}
set
{
Items.Clear();
if (string.IsNullOrWhiteSpace(value))
return;
foreach (var item in value
.Split(new[] { Separator },
StringSplitOptions.RemoveEmptyEntries).Select(item => Deserialize(item)))
Items.Add(item);
}
}
public void AddRange(params T[] items)
{
if (items != null)
foreach (var item in items)
Add(item);
}
protected abstract string Serialize(T item);
protected abstract T Deserialize(string item);
}
public class ScalarStringCollection : ScalarCollectionBase
{
protected override string Deserialize(string item) => item;
protected override string Serialize(string item) => item;
}
public class ScalarCollection : ScalarCollectionBase
where T : IConvertible
{
protected override T Deserialize(string item) =>
(T)Convert.ChangeType(item, typeof(T));
protected override string Serialize(T item) => Convert.ToString(item);
}
}
Загруженный 5 000 записей в простую таблицу на 3 столбца. Отображенный два класса на той таблице, одно использование аннотировало частные поля, и другое использование аннотировало общедоступных методов get. Выполнил 30 выполнений HibernateTemplate.loadAll Spring () сопровождаемый HibernateTemplate.clear () для чистки кэша Сессии. Результаты в мс ниже...
общее количество методов: 6510, среднее число: 217
полевое общее количество: 6586, среднее число: 219
я должен, вероятно, взять другой удар в нем после добавления большего количества свойств к каждому классу, но прямо сейчас различие, кажется, не является статистически значительным.
хорошо, я не могу дать числа ха-ха, но я предположил бы, что доступ к полям посредством отражения не будет 'одним временем' вещь. Каждый объект имеет своих собственных членов парламента, не занимающих официального поста.
я честно не знаю много об отражении, но метод get/методы set должен быть прямым. На самом деле можно попытаться установить один из методов к частному, и я думаю, что он не будет работать, потому что он не может найти метод, в котором он нуждается.
существуют другие проблемы, любят прокси, которые будут влиять на методы получателя, хотя в зависимости от того, как Вы загружаете свои объекты.
Это - все, что я вижу в документации:
атрибут доступа позволяет Вам управлять, как В спящем режиме, получит доступ к свойству во времени выполнения. По умолчанию Будьте в спящем режиме, назовет свойство парой get/set. Если Вы определите доступ = "поле", Будете в спящем режиме, то обойдет получить/установить пару и получит доступ к полю непосредственно, с помощью отражения. Можно определить собственную стратегию доступа свойства путем именования класса, который реализует интерфейс org.hibernate.property. PropertyAccessor.
Мое предположение - то, что отражение в целом будет более высокой стоимостью хотя, но извините.. никакие числа: (