如何让 NHibernate 将给定属性序列化为二进制字段?
我有一个简单的 ASP.NET MVC Web 应用程序,它使用 NHibernate 和 FluentNHibernate 的自动映射功能来进行数据访问。我遇到过一种情况,我希望 NHibernate 将某些类保留为二进制数据。
例如,我有类似这样的东西:
public class User
{
...
// This field will be persisted
public virtual byte[] PortraitData { get; set; }
// This method will get me what I'm actually interested in
public virtual Image GetPortrait()
{
return SerializationHelper.Deserialize<Image>(PortraitData);
}
}
(我将 SerializationHelper
类的实现留给读者想象。它没有做任何复杂的事情,只是将数据序列化和反序列化为字节数组)
我想将上面的代码更改为:
public class User
{
...
public virtual Image Portrait { get; set; }
}
所以基本上我希望告诉 (Fluent)NHibernate 它应该通过将某些类(由我指定)序列化为名称为的二进制字段来持久保存它们实际财产。
(在上面的情况下,我希望它将 Image
序列化到名为 Portrait
的 varbinary
字段中。)
我的实际场景是比这更复杂一些,但这个例子很好地展示了我想要实现的目标。 (意思是:System.Drawing.Image
类并不是我唯一对序列化感兴趣的类。)
我知道 Fluent 或 NHibernate 本身必须有某种配置来允许精确执行这个,但我无法弄清楚。你能告诉我该怎么做吗?
预先感谢您的帮助!
I have a simple ASP.NET MVC web application that uses NHibernate with FluentNHibernate's auto mapping feature for its data access. I have encountered a scenario in which I would like NHibernate to persist some classes as binary data.
For example, I have something similar to this:
public class User
{
...
// This field will be persisted
public virtual byte[] PortraitData { get; set; }
// This method will get me what I'm actually interested in
public virtual Image GetPortrait()
{
return SerializationHelper.Deserialize<Image>(PortraitData);
}
}
(I leave the implementation of the SerializationHelper
class to the reader's imagination. It doesn't do anything complicated, just serializes and deserializes data into byte arrays and back.)
I would like to change the above code to this:
public class User
{
...
public virtual Image Portrait { get; set; }
}
So basically I wish to tell (Fluent)NHibernate that it should persist some classes (specified by me) by serializing them into a binary field with the name of the actual property.
(In the above case, I would like it to serialize the Image
into a varbinary
field called Portrait
.)
The actual scenario I have is a bit more complicated than this, but this example demonstrates very well what I want to achieve. (Meaning: the System.Drawing.Image
class is not the only one I'm interested in serializing.)
I know there must be some kind of configuration in either Fluent or NHibernate itself that allows to do exactly this, but I couldn't figure it out. Could you please tell me how to do this?
Thanks in advance for your help!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
关键是 IUserType 的实现,它本质上是一个用于从 POCO 类型来回转换为 SQL 类型的接口。我用它来翻译枚举<->数据库中的自定义字符串值。看一下 YesNoType 的 NHibernate 代码,它将 true/false 布尔 POCO 类型来回转换为“YES”/“NO”SQL varchar 类型。
要在 Fluent NHibernate 中使用此功能,您可以在 Map 方法上调用 .CustomType() 方法,其中 T 是实现 IUserType 的类。我认为您可以创建一个约定,以便所有 Image 属性都使用实现类,而不是必须在每个属性的基础上定义它,但我不熟悉 Fluent NHibernate 的这一部分。
例如 Map(x => x.Portrait, "PORTRAIT_DATA").CustomType();
The key is an implementation of IUserType, which is essentially an interface you use to translate back and forth from a POCO type to a SQL type. I use it to translate enumerations <-> custom string values in the database. Take a look at the NHibernate code for YesNoType, which translates back and forth between true/false booleans POCO types to "YES"/"NO" SQL varchar types.
To utilize this in Fluent NHibernate, you can invoke the .CustomType() method on the Map method, where T is the class that implements IUserType. I think you could create a convention such that all Image properties would use the implementing class, rather than having to define it on a per-property basis, but I'm not familiar with that part of Fluent NHibernate.
e.g. Map(x => x.Portrait, "PORTRAIT_DATA").CustomType();
您必须实现
IUserType
。然后只需告诉 NH 将其用于该财产即可。
在 xml 中,它是
type="QualifiedName"
;查找 FNH 等效项。You have to implement
IUserType
.Then it's just a matter of telling NH to use it for that property.
In xml it's
type="QualifiedName"
; look for the FNH equivalent.