在 Fluent NHibernate 中映射自定义类型 属性
Mapping a custom type property in Fluent NHibernate
我有一个数据库,用于保存存储在另一个系统中并在代码中反序列化为对象的项目的 Id
。我正在尝试使用 Fluent NHibernate 构建一个域模型实体,该实体由来自数据库和外部服务的数据组成。一个例子会更好地解释这一点。在数据库中,我有一个 table 看起来像这样:
CREATE TABLE entities
(
id integer NOT NULL,
custom_thing text NOT NULL,
CONSTRAINT entities_id_pk PRIMARY KEY (id)
);
它是 PostgreSQL,但问题不是特定于数据库的。现在在代码中我有这些 classes:
class Entity
{
public virtual int Id { get; set; }
public virtual CustomThing CustomThing { get; set; }
}
class CustomThing
{
public string Id { get; set; }
public string Name { get; set; }
}
我正在尝试使用 CustomMap
来定义映射:
class EntityMap : ClassMap<Entity>
{
public EntityMap()
{
Table("entities");
Id(e => e.Id, "id").GeneratedBy.Assigned();
// Map(e => e.CustomThing, "custom_thing");
}
}
问题是:如何映射 CustomThing?这是一个试图映射实体 class 的程序(如果 运行 需要 FluentNHibernate 包和 NpgSQL 到 PostgreSQL 数据库)。为简单起见,我只是在代码中创建 CustomThing
的实例:
class Program
{
// How to use this in mapping?
static CustomThing[] _customThings =
{
new CustomThing {Id = "abc", Name = "ABC"},
new CustomThing {Id = "def", Name = "DEF"}
};
static void Main()
{
using (ISessionFactory sessionFactory = Fluently.Configure()
.Database(PostgreSQLConfiguration.Standard
.ConnectionString(
@"Server=localhost; Database=test_nhibernate; User Id=postgres; Password=little_secret;"))
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<Entity>())
.BuildSessionFactory())
{
using (ISession session = sessionFactory.OpenSession())
{
var entity = session.Get<Entity>(1);
Console.WriteLine($"{entity?.Id} {entity?.CustomThing?.Name}");
}
}
Console.ReadLine();
}
}
输出当然只是 Id 属性 值,因为未定义 CustomThing
的映射。是否可以配置映射,以便我可以将参数传递给它,并以某种方式将 custom_thing
列值映射到 _customThings
中的对象,按 Id 属性?
是的,您可以通过保存 Id
并在代码中获取其余数据来实现,或者将映射器中的所有内容都 return 给您一个对象,如果您select第二个选项你可以按照这个代码:
[Serializable]
public class CustomThingUserType : IUserType {
public new bool Equals(object x, object y) {
if (object.ReferenceEquals(x, y))
return true;
if (x == null || y == null)
return false;
return x.Equals(y);
}
public int GetHashCode(object x) {
if (x == null)
return 0;
return x.GetHashCode();
}
public object NullSafeGet(IDataReader rs, string[] names, object owner) {
if (names.Length == 0)
throw new ArgumentException("Expecting at least one column");
int id = (int)NHibernateUtil.Int32.NullSafeGet(rs, names[0]);
var obj = new CustomThing { Id = id };
// here you can grab your data from external service
return obj;
}
public void NullSafeSet(IDbCommand cmd, object value, int index) {
var parameter = (DbParameter)cmd.Parameters[index];
if (value == null) {
parameter.Value = 0;
}
else {
parameter.Value = ((CustomThing)value).Id;
}
}
public object DeepCopy(object value) {
return value;
}
public object Replace(object original, object target, object owner) {
return original;
}
public object Assemble(object cached, object owner) {
return cached;
}
public object Disassemble(object value) {
return value;
}
public SqlType[] SqlTypes {
get {
return new SqlType[] { new SqlType(DbType.Int32) };
}
}
public Type ReturnedType {
get { return typeof(CustomThing); }
}
public bool IsMutable {
get { return false; }
}
}
我有一个数据库,用于保存存储在另一个系统中并在代码中反序列化为对象的项目的 Id
。我正在尝试使用 Fluent NHibernate 构建一个域模型实体,该实体由来自数据库和外部服务的数据组成。一个例子会更好地解释这一点。在数据库中,我有一个 table 看起来像这样:
CREATE TABLE entities
(
id integer NOT NULL,
custom_thing text NOT NULL,
CONSTRAINT entities_id_pk PRIMARY KEY (id)
);
它是 PostgreSQL,但问题不是特定于数据库的。现在在代码中我有这些 classes:
class Entity
{
public virtual int Id { get; set; }
public virtual CustomThing CustomThing { get; set; }
}
class CustomThing
{
public string Id { get; set; }
public string Name { get; set; }
}
我正在尝试使用 CustomMap
来定义映射:
class EntityMap : ClassMap<Entity>
{
public EntityMap()
{
Table("entities");
Id(e => e.Id, "id").GeneratedBy.Assigned();
// Map(e => e.CustomThing, "custom_thing");
}
}
问题是:如何映射 CustomThing?这是一个试图映射实体 class 的程序(如果 运行 需要 FluentNHibernate 包和 NpgSQL 到 PostgreSQL 数据库)。为简单起见,我只是在代码中创建 CustomThing
的实例:
class Program
{
// How to use this in mapping?
static CustomThing[] _customThings =
{
new CustomThing {Id = "abc", Name = "ABC"},
new CustomThing {Id = "def", Name = "DEF"}
};
static void Main()
{
using (ISessionFactory sessionFactory = Fluently.Configure()
.Database(PostgreSQLConfiguration.Standard
.ConnectionString(
@"Server=localhost; Database=test_nhibernate; User Id=postgres; Password=little_secret;"))
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<Entity>())
.BuildSessionFactory())
{
using (ISession session = sessionFactory.OpenSession())
{
var entity = session.Get<Entity>(1);
Console.WriteLine($"{entity?.Id} {entity?.CustomThing?.Name}");
}
}
Console.ReadLine();
}
}
输出当然只是 Id 属性 值,因为未定义 CustomThing
的映射。是否可以配置映射,以便我可以将参数传递给它,并以某种方式将 custom_thing
列值映射到 _customThings
中的对象,按 Id 属性?
是的,您可以通过保存 Id
并在代码中获取其余数据来实现,或者将映射器中的所有内容都 return 给您一个对象,如果您select第二个选项你可以按照这个代码:
[Serializable]
public class CustomThingUserType : IUserType {
public new bool Equals(object x, object y) {
if (object.ReferenceEquals(x, y))
return true;
if (x == null || y == null)
return false;
return x.Equals(y);
}
public int GetHashCode(object x) {
if (x == null)
return 0;
return x.GetHashCode();
}
public object NullSafeGet(IDataReader rs, string[] names, object owner) {
if (names.Length == 0)
throw new ArgumentException("Expecting at least one column");
int id = (int)NHibernateUtil.Int32.NullSafeGet(rs, names[0]);
var obj = new CustomThing { Id = id };
// here you can grab your data from external service
return obj;
}
public void NullSafeSet(IDbCommand cmd, object value, int index) {
var parameter = (DbParameter)cmd.Parameters[index];
if (value == null) {
parameter.Value = 0;
}
else {
parameter.Value = ((CustomThing)value).Id;
}
}
public object DeepCopy(object value) {
return value;
}
public object Replace(object original, object target, object owner) {
return original;
}
public object Assemble(object cached, object owner) {
return cached;
}
public object Disassemble(object value) {
return value;
}
public SqlType[] SqlTypes {
get {
return new SqlType[] { new SqlType(DbType.Int32) };
}
}
public Type ReturnedType {
get { return typeof(CustomThing); }
}
public bool IsMutable {
get { return false; }
}
}