nhibernate将多行映射到一个对象 [英] nhibernate mapping many rows to one object

查看:131
本文介绍了nhibernate将多行映射到一个对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个相当困难的映射问题。

编辑:reconstituted descritpion

由于历史原因文本不作为文本存储在列中,而是保存在表中。我有几个表,结构如下:

$ $ p $ $ $ $ $ $

序列NOT NULL,
关键字符变化(10),// \
linenumber integer,// /唯一约束
type smallint,
length smallint,//内容字符串的实际长度
内容字符变化(80),
PRIMARY KEY(ID)

文本被保存为任意长度的行,每个实体不同,有时甚至在一个表中不同的文本类型。
i想要将它们映射到内部和映射中处理这些怪癖的类。



到目前为止我的解决方案:

一个隐藏的集合和一个应该只读的虚拟对象。对于加载,总是有效的文本对象,因为坚持内部集合创建它们。

 内部类文本
{
public virtual int Id {get;组; }

public virtual TextType Type {get;组; } // Enum

public virtual int Linenumber {get;组; }
public virtual string Text {get;组; }
}

public class Textmodule
{
public virtual int Id {get;组; }

public virtual string Key {get;组; } // Unique
public virtual TextType Type {get;组; } // Enum

受保护的内部虚拟IList< Textline> Textlines {get;组; }
public virtual string Text
{
get {Textlines.select(t => t.Text).Aggregate(/ * ... * /); }
set {/ *将文本分割为最多80个字符的行,并馈送到文本行* /}
}
}
$ b $ public TextmoduleMap()
{
表(textmodules);
ReadOnly(); //问题:不应该插入和更新,但是插入
Where(linenumber = 1); //开头为1

//不重要,因为它不应该被保存
Id(text => text.Id,id)。

Map(text => text.Key);
HasMany(text => text.Textzeilen)
.Table(textmodules)
.PropertyRef(Key)
.KeyColumn(key)
。组件(c =>
{
c.Map(line => line.Text)
.Columns.Add(content,length)
.CustomType< StringWithLengthUserType>();
c.Map(line => line.Linenumber,linenumber);
})
.Cascade.AllDeleteOrphan()
。 Not.LazyLoad();
;





我的问题是,Readonly不能防止nhibernate在保存时插入它。有什么我可以做到让它工作,或者有人有一个更理智的更理智的域对象?
$ b $编辑2:我摆弄 SQLInsert(SELECT 1); 但我得到异常意外的行数-1,期望1



感谢您的时间

解决方案

我发现了一个相当丑陋的方式,可能不是非常便携的

<$ p $公共TextmoduleMap()
{
...
ReadOnly();
SqlInsert(DROP TABLE IF EXISTS temp; CREATE TEMP TABLE temp(id int); INSERT INTO temp(id)VALUES(1););
SqlDelete(DROP TABLE IF EXISTS temp; CREATE TEMP TABLE temp(id int); INSERT INTO temp(id)VALUES(1););

...
}

更好的方法仍然欢迎

i have a rather difficult mapping problem.

EDIT: reformulated descritpion

for historical reasons texts are not stored in a column as text, instead they are saved in tables. i have several tables with following structure:

TABLE SomeEntityTexts
(
  id serial NOT NULL,
  key character varying(10),      // \
  linenumber integer,             // / unique constraint
  type smallint,
  length smallint,                // actual length of content string
  content character varying(80),
  PRIMARY KEY (id)
)

text is saved as lines with arbitrary length, different für each entity and sometimes even for different texttypes in one table. i would like to map them to classes which handle these quirks inside and in mappings.

my solution so far:

a hidden collection and a dummy object which should be readonly. For loading there are always valid Text-objects because persisting the inner collection creates them.

internal class Textline
{
    public virtual int Id { get; set; }

    public virtual TextType Type { get; set; }   // Enum

    public virtual int Linenumber { get; set; }
    public virtual string Text { get; set; }
}

public class Textmodule
{
    public virtual int Id { get; set; }

    public virtual string Key { get; set; }      // Unique
    public virtual TextType Type { get; set; }   // Enum

    protected internal virtual IList<Textline> Textlines { get; set; }
    public virtual string Text
    {
        get { Textlines.select(t => t.Text).Aggregate(/* ...*/); }
        set { /* split text to lines with max 80 chars and feed to Textlines*/}
    }
}

public TextmoduleMap()
{
    Table("textmodules");
    ReadOnly();    // problem: shouldnt insert and update at all, but does insert
    Where("linenumber = 1");  // starts with 1

    // doesnt matter because it shouldnt be saved
    Id(text => text.Id, "id").GeneratedBy.Custom<SimpleGenerator>();

    Map(text => text.Key);
    HasMany(text => text.Textzeilen)
        .Table("textmodules")
        .PropertyRef("Key")
        .KeyColumn("key")
        .Component(c =>
        {
            c.Map(line => line.Text)
                .Columns.Add("content", "length")
                .CustomType<StringWithLengthUserType>();
            c.Map(line => line.Linenumber, "linenumber");
        })
        .Cascade.AllDeleteOrphan()
        .Not.LazyLoad();
        ;
}

My problem is, that Readonly doesnt prevent nhibernate from inserting it on save. Is there anything i can do to get it work or does someone has a better idea for a more sane domain object?

Edit2: I fiddled with SQLInsert("SELECT 1"); but i get exception "unexpected rowcount -1, expect 1"

thanks for your time

解决方案

i found a rather ugly way which is probably not very portable

public TextmoduleMap()
{
    ...
    ReadOnly();
    SqlInsert("DROP TABLE IF EXISTS temp; CREATE TEMP TABLE temp(id int); INSERT INTO temp (id) VALUES (1);");
    SqlDelete("DROP TABLE IF EXISTS temp; CREATE TEMP TABLE temp(id int); INSERT INTO temp (id) VALUES (1);");

    ...
}

Better ways are still welcome

这篇关于nhibernate将多行映射到一个对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆