实体框架,当多对多的人持有数据时

时间:2011-01-17 01:28:01

标签: c# .net entity-framework-4 entity-relationship ef4-code-only

我正在使用Entity Framework CTP5。

我有这样的架构:

  • 一个组包含许多文字描述。
  • 文字描述有很多文字。
  • 语言有很多文本。

所以有4个表。 群组一对多 DEscriptions 多对多文本多对一语言

my model

所以我有一个多对多关系,其中关系也包含数据。

Text和TextDescription的定义(因为我们可以查询我在这里没有添加它们的ID和语言的ID)

public class Text
{
    public int TextID { get; set; }
    public int TextDescriptionID { get; set; }
    public int LanguageID { get; set; }
    public string OriginalText { get; set; }
    public bool IsValid { get; set; }
    public DateTime Added { get; set; }
    public DateTime Updated { get; set; }
    public Language Language { get; set; }
    public TextDescription TextDescription { get; set; }

    public static Text GetMissingText(string input)
    {
        Text text = new Text();
        text.OriginalText = "Missing: " + input;
        text.IsValid = true;
        text.TextDescription = new TextDescription()
                               {
                                   IsStatic = true,
                                   Name = input,
                                   IsMultiline = false,
                               };

        return text;
    }
}

public class TextDescription
{
    public int TextDescriptionId { get; set; }
    public int TextDescriptionGroupId { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public bool UseHtml { get; set; }
    public bool IsMultiline { get; set; }
    public bool IsStatic { get; set; }

    public TextDescriptionGroup TextDescriptionGroup { get; set; }
    public virtual ICollection<Text> Texts { get; set; }

    public static TextDescription GetNewItem(int textDescriptionGroupId)
    {
        var item = new TextDescription();
        item.Name = item.Description = "n/a";
        item.UseHtml = item.IsMultiline = item.IsMultiline = false;
        item.TextDescriptionGroupId = textDescriptionGroupId;
        return item;
    }
}

添加新语言或插入新文本时...多对多关系未插入数据库。 (想想这将是一个坏主意,所以最后,如果这是唯一的解决方案,我能够做到这一点)

因此,当我需要从数据库中获取特定组的所有文本时,如何以智能方式处理此问题,如果有一种语言,则还可以获得翻译。< / p>

我无法启动翻译对象,因为它可能不存在。如果我开始从Text实体查询...如何在不首先获取所有语言的情况下选择一种语言。

 repo.Find(x => 
           x.GroupId == groupId && 
           x.Translation.Any(a => a.LanguageID == id.Value)
 );

我迷失在这里......任何有智能的方式......所以我不必查询数据库中的所有文本...然后查询每个项目......看看是否有翻译?或者只是制作一个新的空的。

在SQL中我会这样做:

SELECT TD.Name, T.OriginalText FROM TextDescriptions TD
LEFT JOIN Texts T ON TD.TextDescriptionId = T.TextDescriptionId
WHERE TextDescriptionGroupId = 41 AND ISNULL(T.LanguageId, 1) = 1

即使现在没有记录,上面的SQL也会给我元素,我得到这些值的NULL。然后我可以处理它我的代码并避免延迟加载。

但是我可以在Entity Framework中获得相同的行为。我可以看到EF4可能会出现一些问题进行映射...因为我要从TextDesciptions转到文本...而TextDesciptions有一个文本列表......但是这里......我只想要1或NULL,或者只是尚未添加到数据库的新实体。

期待一些有趣的答案。

MVH

1 个答案:

答案 0 :(得分:1)

现在......如果找不到其他解决方案,我将运行以下SQL脚本来插入空记录。这样我肯定当用户想要编辑它并且在保存它之前不必确保其存在时记录就在那里。也许还避免了一些习惯性的Linq查询。

我只需要运行这个SQL 2位置。添加新语言或新建TextDesciption时。

INSERT INTO Texts 
SELECT TD.TextDescriptionId, L.LanguageId, '', 0, GETDATE(), GETDATE(), L.TwoLetterISOLanguageName 
FROM TextDescriptions TD 
INNER JOIN Languages L ON 1 = 1 
LEFT JOIN Texts T ON 
T.TextDescriptionId = TD.TextDescriptionId AND 
T.LanguageId = L.LanguageId 
WHERE TextId IS NULL