gpt4 book ai didi

c# - 如何在具有自己的用户类型的延迟加载属性上激活二级缓存?

转载 作者:可可西里 更新时间:2023-11-01 08:28:56 24 4
gpt4 key购买 nike

前言:
在我的应用程序中,我将原始 WAV 数据作为 byte[] 存储在数据库中。在我的域模型中,有一个类 PcmAudioStream 代表原始 WAV 数据。我创建了 NHibernate 的 IUserType 的实现,以在我的类和 byte[] 之间进行转换。
有几个使用 PcmAudioStream 类的类,所有这些类都映射到数据库表。为避免在从此类表中检索行时始终加载所有 WAV 数据,我创建了 Fluent NHibernate 的 IUserTypeConvention 的实现,该实现指定应始终延迟加载这些属性。
所有这些都非常有效。

问题:
因为这些 PcmAudioStream 的内容很少改变,所以我想将检索到的实例放在二级缓存中。现在,我知道了如何为一个完整的类激活二级缓存,但我如何只为延迟加载的属性实现这一点?


我的领域模型的相关部分如下所示:

public class User : Entity
{
public virtual string FirstName { get; set; }
public virtual string LastName { get; set; }
public virtual PcmAudioStream FullNameRecording { get; set; }
// ...
}

映射很简单(注意:那不是我的映射,我使用的是约定,但它是等价的):

public class UserMap : ClassMap<User>
{
public UserMap()
{
Id(x => x.Id);
Map(x => x.FirstName);
Map(x => x.LastName);
Map(x => x.FullNameRecording).CustomType<PcmAudioStreamAsByteArray>();
}
}

最佳答案

您可以使用私有(private)静态缓存来完成此操作。设置起来要多一些工作,但不需要额外的类或对域模型进行公共(public)更改。一个很大的缺点是条目不会从缓存中删除,但您可以使用自定义集合或限制条目数量的“全局”缓存。

public class Entity
{
public virtual int Id { get; protected set; }
}

public class PcmAudioStream
{}

public class User : Entity
{
private static readonly IDictionary<int, PcmAudioStream> _fullNameRecordingCache;

private PcmAudioStream _fullNameRecording;

static User()
{
_fullNameRecordingCache = new Dictionary<int, PcmAudioStream>();
}

public virtual string FirstName { get; set; }
public virtual string LastName { get; set; }
public virtual PcmAudioStream FullNameRecording
{
get
{
if (_fullNameRecordingCache.ContainsKey(Id))
{
return _fullNameRecordingCache[Id];
}
// May need to watch for proxies here
_fullNameRecordingCache.Add(Id, _fullNameRecording);
return _fullNameRecording;
}
set
{
if (_fullNameRecordingCache.ContainsKey(Id))
{
_fullNameRecordingCache[Id] = value;
}
_fullNameRecording = value;
}
}
// ...
}

映射:

public class UserMap : ClassMap<User>
{
public UserMap()
{
Id(x => x.Id);
Map(x => x.FirstName);
Map(x => x.LastName);
Map(x => x.FullNameRecording).CustomType<PcmAudioStreamAsByteArray>()
.Access.CamelCaseField(Prefix.Underscore);
}
}

根据评论编辑:

我看不出有可能在用户类型中实现这一点,因为 IDataReader 已经在 NullSafeGet 中打开。我认为您可以在实现 IPreLoadEventListener 的监听器中执行此操作,但这不允许您使缓存无效。我认为这两种选择都不可行。

在进一步考虑之后,我仍然认为我的原始解决方案(或变体)是最佳选择。我理解(并分享)您对干净域模型的渴望,但有时需要妥协,我的解决方案不会更改模型的公共(public)成员或需要任何其他引用。另一个理由是对象是第一个知道记录已更改并且需要在缓存中替换或添加到缓存中的对象。

关于c# - 如何在具有自己的用户类型的延迟加载属性上激活二级缓存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8107419/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com