【问题标题】:Nhibernate Class mapping appending "_id" to the column name将“_id”附加到列名的 Nhibernate 类映射
【发布时间】:2016-04-07 06:23:13
【问题描述】:

我的数据库 Question 和 LanguageCode 中有两个表

以下是问题表的结构:

QuestionId int
Text varchar(100)
LanguageCode uniqueidentifier

以下是LanguageCode表的结构:

Id uniqueidentifier
Name varchar(20)

现在我想使用 NHibernate 映射这两个实体,因为我创建了 Question & LanguageCode 实体:

问题实体:

public class Question
{
    public Question()
    {           
    }
    public virtual int Id { get; set; }

    public virtual string Text { get; set; }

    public  virtual LanguageCode LanguageCode { get; set; }
}

语言代码实体:

public class LanguageCode
{
    public LanguageCode()
    {

    }
    public virtual  Guid Id { get; set; }

    public virtual  string Name { get; set; }
}

下面是这两个实体类的映射关系

问题地图:

internal class QuestionMap : ClassMap<Question>
{
    public QuestionMap()
    {
        ReadOnly();
        Table("Question");
        Id(x => x.Id).Column("Id").GeneratedBy.Assigned();
        Map(x => x.Text);
        HasOne(x => x.LanguageCode);
    }
}

语言代码图:

internal class LanguageCodeMap:ClassMap<LanguageCode>
{
    public LanguageCodeMap()
    {
        ReadOnly();
        Table("LanguageCode");
        Id(x => x.Id).Column("Id").GeneratedBy.Assigned();
        Map(x => x.Name);
    }
}

现在执行以下代码:

LanguageCode languageCodeAlias = null;
Question question = null;
var res = session.QueryOver(()=>question)
                               .JoinAlias(() => question.LanguageCode, () => languageCodeAlias)

.WhereRestrictionOn(x=>x.Id).IsIn(questionIds).List();

我收到一个 SQLException,下面是在执行时创建的查询:

 SELECT this_.Id as Id1_1_, this_.Text as Text2_1_1_,
 this_.LanguageCode_id as Language5_1_1_,
 languageco1_.Id as Id0_0_, languageco1_.Name as Name0_0_ FROM
 [Question] this_ inner join [LanguageCode] languageco1_ on
 this_.LanguageCode_id=languageco1_.Id WHERE this_.Id in (157827)

很明显,它使用 LanguageCode_id 而不是表名 LanguageCode,我不知道如何解决这个问题。 所以请帮我解决这个问题,如果需要更多详细信息,请告诉我。

【问题讨论】:

  • 您需要为HasOne指定列名

标签: c# nhibernate


【解决方案1】:

我会使用proper reference,而不是HasOne

internal class QuestionMap: ClassMap<Question>
{
    public QuestionMap()
    {
        ReadOnly();
        Table("Question");
        Id(x => x.Id).Column("Id").GeneratedBy.Assigned();
        Map(x => x.Text);
        References(x => x.LanguageCode).Column("LanguageCode");
    }
}

HasOne 代表one-to-one special cases,我希望您有很多使用相同语言代码的问题。

【讨论】:

  • 不走运!我没有 LanguageCodeId 列。
  • 如何将 LanguageCode 链接到问题?你应该有一些外键。
  • 是的,但问题是查询将“_id”附加到语言代码列,它应该使用“语言代码”而不是“语言代码_id”。
  • 好吧,然后在映射中使用您的列名。
  • 和问题的查询是一样的吗?
【解决方案2】:

好吧,我通过添加以下类找到了解决方案:

public class CustomForeignKeyConvention : IReferenceConvention
{
    public void Apply(IManyToOneInstance instance)
    {
        instance.Column(instance.Class.Name);
    }
}

并在 SessionFactory 中配置:

Fluently.Configure()
             .Database(ConfigureDb())
             .Mappings(m=>m.AutoMappings.Add(AutoMap.AssemblyOf<QuestionMap>(cfg)
             .Conventions.AddFromAssemblyOf<CustomForeignKeyConvention>()))
             .BuildSessionFactory();

如果列名类似于“columnname_abc”,那么我们可以更改

instance.Column(instance.Class.Name) 到 instance.Column(instance.Class.Name + "_abc");

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多