Entity Framework 嵌套 table 查询到 JSON

Entity Framework nested table query to JSON

public class Module
{
    public int id { get; set; }
    public string moduleName { get; set; }
    //navigation property
    public virtual HashSet<Policy> policies { get; set; }
}

public class Policy
{
    public int id { get; set; }
    //foreign keys
    public int subscriberId { get; set; }
    //navigation properties
    public virtual Subscriber subscriber { get; set; }
}

public class Subscriber
{
    public int id { get; set; }
    public string name { get; set; }
    public int subscriptionId { get; set; }
    // Navigation property 
    public virtual HashSet<Policy> policies { get; set; }
}

我有 3 个相关对象。

Module - Policy - Subscriber

我需要以JSON格式列出某个模块下的所有策略和订阅者。由于我在网上找到的帖子,我创建了这个查询:

        return db.modules
            .Where(m => m.id == id)
            .Include (m => m.policies.Select(p => p.subscriber))
            .Select(m => new {
                m.id,
                m.moduleName,
                m.policies
            }) ;

这只给出了下面的结果。如您所见,政策下订阅者实体的详细信息不存在 (NULL) :( 有什么问题吗?

[{"id":1,"moduleName":"module1",
  "policies":[{"id":1,"subscriberId":1,"subscriber":null}]}]

由于您在 Select 方法中使用了动力学,因此您必须像这样构建它:

return db.modules
    .Where(m => m.id == id)
    .Include (m => m.policies.Select(p => p.subscriber))
    .Select(m => new {
        m.id,
        m.moduleName,
        policies = m.policies.Select(p => new
        {
            p.id,
            p.subscriberId,
            subscriber = new
            {
                p.subscriber.id,
                p.subscriber.name,
                p.subscriber.subscriptionId,
            }
        }
    });

我通常使用真正的 Dto 类 所以如果 Dto 需要更新,重构将正常工作。我也会考虑使用 DtoFactory 来处理构造,但是您可以像这样使用 linq 来完成它:

public class ModuleDto
{
    public int id { get; set; }
    public string moduleName { get; set; }
    public IEnumerable<PolicyDto> policies { get; set; }
}
public class PolicyDto
{
    public int id { get; set; }
    public int subscriberId { get; set; }
    public SubscriberDto subscriber { get; set; }
}
public class SubscriberDto
{
    public int id { get; set; }
    public string name { get; set; }
    public int subscriptionId { get; set; }
}    

...other code here...

return db.modules
    .Where(m => m.id == id)
    .Include (m => m.policies.Select(p => p.subscriber))
    .Select(m => new ModuleDto {
        m.id,
        m.moduleName,
        policies = m.policies.Select(p => new PolicyDto
        {
            p.id,
            p.subscriberId,
            subscriber = new SubsciberDto
            {
                p.subscriber.id,
                p.subscriber.name,
                p.subscriber.subscriptionId,
            }
        }
    });

读linq语句有点乱。这就是我通常使用 DtoFactory 从模型生成 Dto 的原因。