从多个表(C#Entity)获取数据,通过外键链接,转换为匿名对象

时间:2016-08-26 09:52:46

标签: c# sql-server json entity-framework linq

我是Entity / Linq / Lambda的新手,我遇到以下问题:

我有一个Web应用程序,它通过ASP.NET MVC提供JSON Api。数据库是MSSQL,我使用C#实体框架作为数据访问层。

从单个表中获取数据时,我需要将其转换为匿名对象,然后才能将其转换为JSON以避免循环引用错误。

这是一个简化的示例,但请以这些表为例:

DB Schema

如果我只想返回JSON中的所有翻译器,我就是这样做的:

DBEntities db = new DBEntities();

var data = db.Translator.Select(x => new
        {
            TranslatorID = x.TranslatorID,
            FirstName = x.FirstName,
            LastName = x.LastName,
            Email = x.Email,
            Referenced = x.TranslatorLanguage.Count != 0
        });

        return Json(data, JsonRequestBehavior.AllowGet);

Entity生成的Model类看起来像这样:

public partial class Translator
{

    public Translator()
    {
        this.TranslatorLanguage = new HashSet<TranslatorLanguage>();
    }

    public int TranslatorID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }

    public virtual ICollection<TranslatorLanguage> TranslatorLanguage { get; set; }
}

public partial class TranslatorLanguage
{
    public int TranslatorLanguageID { get; set; }
    public int SourceLanguageID { get; set; }
    public int TargetLanguageID { get; set; }

    public virtual Translator Translator { get; set; }
    public virtual Language Language1 { get; set; }
    public virtual Language Language2 { get; set; }
}

public partial class Language
{

    public Language()
    {
        this.TranslatorLanguage = new HashSet<TranslatorLanguage>();
        this.TranslatorLanguage1 = new HashSet<TranslatorLanguage>();
    }

    public int TranslatorLanguageID { get; set; }
    public int SourceLanguageID { get; set; }
    public int TargetLanguageID { get; set; }

    public virtual ICollection<TranslatorLanguage> TranslatorLanguage { get; set; }
    public virtual ICollection<TranslatorLanguage> TranslatorLanguage1 { get; set; }
}

但我希望能够为所有翻译器返回一个JSON,其中每个Translator-object包含一个带有TranslatorLanguage条目的数组,并且每个源语言和目标语言都有它的varchar代码和描述值。

我不知道怎么回事, 提前谢谢。

1 个答案:

答案 0 :(得分:1)

与将项目(选择)Translator投影到匿名类型的方式相同,您可以将TranslatorLanguage投影到嵌套的匿名类型列表。

由于您已经定义了必要的导航属性,因此非常简单 - 您只需要跟踪查询中的导航属性(即导航),就好像它们是对象一样:

var data = db.Translator.Select(t => new
{
    TranslatorID = t.TranslatorID,
    FirstName = t.FirstName,
    LastName = t.LastName,
    Email = t.Email,
    Languages = t.TranslatorLanguage.Select(tl => new
    {
        SourceCode = tl.Language1.Code,
        SourceDescription = tl.Language1.Description,
        TargetCode = tl.Language2.Code,
        TargetDescription = tl.Language2.Description,
    }).ToList()
}).ToList();