gpt4 book ai didi

c# - NHibernate 3.2 通过代码映射忽略我的 IUserType

转载 作者:行者123 更新时间:2023-12-03 04:58:41 24 4
gpt4 key购买 nike

我有一个 LocalizedString 类,用于存储单个值的本地化。这个概念大致基于 post by Fabio Maulo .

我在 NHibernate 3.2 中使用新的 Mapping-By-Code 概念,但它似乎忽略了 IUserType 实现,因为当它生成 SQL 时,它会创建一个具有不同名称的列并使用默认字符串 NVARCHAR(255) 类型。

我正在尝试映射这个简单的类

public class Region : Entity
{
/// <summary>
/// Initializes a new instance of the <see cref="Region"/> class.
/// </summary>
public Region()
{
}

/// <summary>
/// Gets or sets the localized name of the <see cref="Region"/>.
/// </summary>
public virtual LocalizedString Name { get; set; }
}

生成的 SQL 为

create table Regions (RegionId INT not null, Item NVARCHAR(255) not null, primary key (RegionId))

这里的Item列应该被称为Name并且它应该是XML类型。我假设列名称来自 LocalizedString 的索引器名称。

这是我的 NHibernate 配置(它不完整,我正在构建约定)

private static Configuration CreateNHibernateConfiguration()
{
var cfg = new Configuration();
cfg.Proxy(p => p.ProxyFactoryFactory<NHibernate.Bytecode.DefaultProxyFactoryFactory>())
.DataBaseIntegration(db =>
{
db.ConnectionStringName = "***";
db.Dialect<MsSql2008Dialect>();
db.BatchSize = 500;
});

var mapper = new ConventionModelMapper();
var baseEntityType = typeof(Entity);
mapper.IsEntity((t, declared) => baseEntityType.IsAssignableFrom(t) && baseEntityType != t && !t.IsInterface);
mapper.IsRootEntity((t, declared) => baseEntityType.Equals(t.BaseType));

mapper.BeforeMapClass += (mi, t, map) =>
{
map.Table(Inflector.MakePlural(t.Name));
map.Id(x =>
{
x.Column(t.Name + "Id");
});
};

mapper.BeforeMapManyToOne += (insp, prop, map) =>
{
map.Column(prop.LocalMember.GetPropertyOrFieldType().Name + "Id");
map.Cascade(Cascade.Persist);
};

mapper.BeforeMapBag += (insp, prop, map) =>
{
map.Key(km => km.Column(prop.GetContainerEntity(insp).Name + "Id"));
map.Cascade(Cascade.All);
};

mapper.BeforeMapProperty += (insp, prop, map) =>
{
map.NotNullable(true);
};

var exportedTypes = baseEntityType.Assembly.GetExportedTypes();
mapper.AddMappings(exportedTypes.Where(t => t.Namespace.EndsWith("Mappings", StringComparison.Ordinal)));

var mapping = mapper.CompileMappingFor(exportedTypes.Where(t => t.Namespace.EndsWith("Data", StringComparison.Ordinal)));

cfg.AddDeserializedMapping(mapping, "MyModel");
SchemaMetadataUpdater.QuoteTableAndColumns(cfg);

return cfg;
}

这是我的 LocalizedString 类的 IUserType 定义:

/// <summary>
/// Defines a string that can have a different value in multiple cultures.
/// </summary>
public sealed partial class LocalizedString : IUserType
{
object IUserType.Assemble(object cached, object owner)
{
var value = cached as string;
if (value != null)
{
return LocalizedString.Parse(value);
}

return null;
}

object IUserType.DeepCopy(object value)
{
var toCopy = value as LocalizedString;
if (toCopy == null)
{
return null;
}

var localizedString = new LocalizedString();
foreach (var localizedValue in toCopy.localizedValues)
{
localizedString.localizedValues.Add(localizedValue.Key, localizedValue.Value);
}

return localizedString;
}

object IUserType.Disassemble(object value)
{
var localizedString = value as LocalizedString;
if (localizedString != null)
{
return localizedString.ToXml();
}

return null;
}

bool IUserType.Equals(object x, object y)
{
if (x == null && y == null)
{
return true;
}

if (x == null || y == null)
{
return false;
}

var localizedStringX = (LocalizedString)x;
var localizedStringY = (LocalizedString)y;

if (localizedStringX.localizedValues.Count() != localizedStringY.localizedValues.Count())
{
return false;
}

foreach (var value in localizedStringX.localizedValues)
{
if (!localizedStringY.localizedValues.ContainsKey(value.Key) || localizedStringY.localizedValues[value.Key] == value.Value)
{
return false;
}
}

return true;
}

int IUserType.GetHashCode(object x)
{
if (x == null)
{
throw new ArgumentNullException("x");
}

return x.GetHashCode();
}

bool IUserType.IsMutable
{
get { return true; }
}

object IUserType.NullSafeGet(System.Data.IDataReader rs, string[] names, object owner)
{
if (rs == null)
{
throw new ArgumentNullException("rs");
}

if (names == null)
{
throw new ArgumentNullException("names");
}

if (names.Length != 1)
{
throw new InvalidOperationException("names array has more than one element. can't handle this!");
}

var val = rs[names[0]] as string;

if (val != null)
{
return LocalizedString.Parse(val);
}

return null;
}

void IUserType.NullSafeSet(System.Data.IDbCommand cmd, object value, int index)
{
if (cmd == null)
{
throw new ArgumentNullException("cmd");
}

var parameter = (DbParameter)cmd.Parameters[index];

var localizedString = value as LocalizedString;
if (localizedString == null)
{
parameter.Value = DBNull.Value;
}
else
{
parameter.Value = localizedString.ToXml();
}
}

object IUserType.Replace(object original, object target, object owner)
{
throw new NotImplementedException();
}

Type IUserType.ReturnedType
{
get { return typeof(LocalizedString); }
}

NHibernate.SqlTypes.SqlType[] IUserType.SqlTypes
{
get { return new[] { new XmlSqlType() }; }
}
}

最佳答案

您不应在域模型中使用 IUserType。

IUserType 接口(interface)实际上应该被称为 IUserTypeMapper 之类的名称,并且您必须在映射中显式指定它。

我建议您重新阅读该帖子。


更新:尝试按照约定映射您的类型:

mapper.BeforeMapProperty +=
(insp, prop, map) =>
{
if (/*determine if this is member should be mapped as LocalizedString*/)
map.Type<LocalizedString>();
};

当然,“确定是否...”部分将是您确定的内容,例如以“Localized”开头的属性名称、自定义属性或您想要的任何内容。

关于c# - NHibernate 3.2 通过代码映射忽略我的 IUserType,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6611681/

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