使用一种类型在FluentNHibernate中存储字段,但通过方法访问另一种类型

时间:2009-09-06 00:41:46

标签: c# nhibernate serialization fluent-nhibernate

我正在数据库中创建一个消息队列。每个排队的项目都存储一个ID和其他一些东西。但关键领域是IncomingMessage。在数据库中,我存储IncomingMessage的序列化版本,因为它可以是多种类型之一(如NewWorkorderMessage或EmployeeStatusChangeMes​​sage)。所以我的QueuedMessage类_incomingMessage中的字段是一个字符串。

但是,我想避免通常需要的公共虚拟字符串QueuedMessage {get; set;}业务,只需要一个公共对象GetMessage()和公共SetMessage(对象消息)方法来处理自动序列化的.NET类进入XML。当然,调用应用程序想要处理Message类的实例,而不是它必须序列化/反序列化的XML。

使用FluentNHibernate我不知道该怎么做。我尝试了几种不同的方法,如下所示,但这仍然要求我拥有该属性。

有什么想法吗?感谢。

            Map(x => x.IncomingMessage)
            .Not.Nullable()
            .WithLengthOf(3000)
            .Access.AsReadOnlyPropertyThroughCamelCaseField(Prefix.Underscore);

1 个答案:

答案 0 :(得分:0)

嗯,我做过类似于Images的事情。我将图像作为blob存储在DB中,但是想要在我的POCO类中将它们作为Image类访问。我是通过使用IPropertyAccessor接口完成的。

My Fluent NHibernate看起来像这样

        Map(entity => entity.Image)
            .Access.Using<ImagePropertyAccessor>()
            .Nullable();

我的IPropertyAccessor看起来像这样:

public class ImagePropertyAccessor : IPropertyAccessor
{
    #region Setter

    private class ImageGetterSetter : IGetter, ISetter {
        PropertyInfo _property;
        ImageFormat _imageFormat;
        public ImageGetterSetter(PropertyInfo property, ImageFormat imageFormat)
        {
            if (property == null) throw new ArgumentNullException("property");
            if (property.PropertyType != typeof(Image)) throw new ArgumentException("property");
            _property = property;
            _imageFormat = imageFormat;
        }

        public void Set(object target, object value) {
            var image = Deserialise((byte[]) value);
            _property.SetValue(target, image, null);
        }

        public object Get(object target)
        {
            var image = (Image)_property.GetValue(target, null);
            var data = Serialise(image);
            return data;
        }

        private byte[] Serialise(Image image)
        {
            if (image == null)
                return null;
            var ms = new MemoryStream();
            image.Save(ms, _imageFormat);
            return ms.ToArray();
        }

        private Image Deserialise(byte[] data)
        {
            if (data == null || data.Length == 0)
                return null;
            var ms = new MemoryStream(data);
            return Image.FromStream(ms);
        }

        public object GetForInsert(object owner, IDictionary mergeMap, ISessionImplementor session)
        {
            return Get(owner);
        }

        public Type ReturnType
        {
            get { return typeof (byte[]); }
        }

        public string PropertyName {
            get { return _property.Name; }
        }

        public MethodInfo Method {
            get { return null; }
        }
    }

    #endregion

    public IGetter GetGetter(Type theClass, string propertyName) {
        return new ImageGetterSetter(theClass.GetProperty(propertyName), ImageFormat.Bmp);
    }

    public ISetter GetSetter(Type theClass, string propertyName) {
        return new ImageGetterSetter(theClass.GetProperty(propertyName), ImageFormat.Bmp);
    }

    public bool CanAccessThroughReflectionOptimizer {
        get { return false; }
    }
}

我不知道,或者更确切地说没有调查过,是将序列化/反序列化推入NHibernate的效果。显然,这有额外的开销。在我的例子中,它并不太糟糕,因为我没有处理大量的实体和数据。出于性能原因,您可能最好使用反序列化的字符串并公开自己的方法来转换它。但是IPropertyAccessor很适合保留POCO类的设计。