代码之家  ›  专栏  ›  技术社区  ›  Kim Johansson

如何跨多个表映射字典

  •  -1
  • Kim Johansson  · 技术社区  · 15 年前

    我有四张桌子:

    CREATE TABLE [Languages]
    (
      [Id] INTEGER IDENTITY(1,1) NOT NULL,
      [Code] NVARCHAR(10) NOT NULL,
      PRIMARY KEY ([Id]),
      UNIQUE INDEX ([Code])
    );
    
    CREATE TABLE [Words]
    (
      [Id] INTEGER IDENTITY(1,1) NOT NULL,
      PRIMARY KEY ([Id])
    );
    
    CREATE TABLE [WordTranslations]
    (
      [Id] INTEGER IDENTITY(1,1) NOT NULL,
      [Value] NVARCHAR(100) NOT NULL,
      [Word] INTEGER NOT NULL,
      [Language] INTEGER NOT NULL,
      PRIMARY KEY ([Id]),
      FOREIGN KEY ([Word]) REFERENCES [Words] ([Id]),
      FOREIGN KEY ([Language]) REFERENCES [Languages] ([Id])
    );
    
    CREATE TABLE [Categories]
    (
      [Id] INTEGER IDENTITY(1,1) NOT NULL,
      [Word] INTEGER NOT NULL,
      PRIMARY KEY ([Id]),
      FOREIGN KEY ([Word]) REFERENCES [Words] ([Id])
    );
    

    因此,您可以通过word->wordtranslation->语言关系获取类别的名称。

    这样地:

    SELECT TOP 1 wt.Value
    FROM [Categories] AS c
    LEFT JOIN [WordTranslations] AS wt ON c.Word = wt.Word
    WHERE wt.Language = (
      SELECT TOP 1 l.Id
      FROM [Languages]
      WHERE l.[Code] = N'en-US'
    )
    AND c.Id = 1;
    

    这将返回id=1的类别的en-us翻译。

    我的问题是如何使用以下类来映射:

    public class Category
    {
      public virtual int Id { get; set; }
      public virtual IDictionary<string, string> Translations { get; set; }
    }
    

    得到与上面的sql查询相同的结果是:

    Category category = session.Get<Category>(1);
    
    string name = category.Translations["en-US"];
    

    而“name”现在将在en-us中包含类别的名称。

    类别映射到类别表。

    你会怎么做,甚至有可能吗?

    2 回复  |  直到 15 年前
        1
  •  1
  •   Morten Mertner    15 年前

    如果您使用的是linq,那么您应该能够摆脱这样的问题:

    public Category GetCategory(int categoryId)
    { 
        var translations = from c in db.Categories
                           join wt in db.WordTranslations on c.Word equals wt.Word
                           join l in db.Languages on l.Id equals wt.Language
                           where c.Id == categoryId
                           select new { Key=l.Code, Value=wt.Word };
        return new Category { Id=categoryId, Translations=translations.ToDictionary() };
    }
    

    我没有编译检查这个,所以您可能需要对语法进行一些处理才能得到正确的结果,但从概念上讲,它应该可以满足您的需要。

        2
  •  0
  •   Tom Carter    15 年前

    你看过用 SetResultTransformer变压器 . nhibernate提供了这个函数,用于将结果集映射到类或其他结构。使用aliastoEntityMap的transfrom将每一行转换为一个属性字典——这可能是您要查找的。

    见第13.4节 this