Include返回的实体框架限制属性

时间:2013-06-11 11:36:09

标签: c# asp.net-web-api entity-framework-5

我正在使用Include()将相关对象添加到查询结果中。但是,我不希望结果集中的相关表的所有字段。我已经设法提出以下解决方案,但是有没有更好的方法呢?

由于客户端的限制,我无法返回只有所需字段的新类型。我需要返回正确的类型(Models.Message)。

private void LimitProperties(object entity, List<string> keepProps) {
    if (entity == null)
    {
        return;
    }

    PropertyInfo[] props = entity.GetType().GetProperties();
    foreach (PropertyInfo prop in props)
    {
        if (!keepProps.Contains(prop.Name))
        {
            prop.SetValue(entity, null);
        }
    }
}

public Models.Message GetMessageByID(int messageID) {
    List<string> _validProps = new List<string> { "ID", "Name", "Title" };

    Models.Message message = DbContext.Messages
        .Include(m => m.RefChannel)
        .Include(m => m.RefSender)
        .Include(m => m.RefRecipient)
        .FirstOrDefault(m => m.ID == messageID);

    // limit the number of returned fields
    if (message != null)
    {
        LimitProperties(message.RefChannel, _validProps);
        LimitProperties(message.RefSender, _validProps);
        LimitProperties(message.RefRecipient, _validProps);
    }

    return message;
}

2 个答案:

答案 0 :(得分:3)

以这种方式使RefSender类型的对象具有一些null值太危险了。因为不清楚它是真正的空还是未加载的空

据我了解,您关心的是序列化对象的丰富程度,它将被用作网络上的dto。在这种情况下,您可以使用Custom Serializer来忽略您的字段,以便不参与序列化,甚至可以使用某些属性(如[NonSerialize]]忽略某些字段。

同样如上所述,在您说过的情况下,一种解决方案是创建一个包含EntityBaseIdName的基类Title

答案 1 :(得分:0)

我最终将AsNoTracking()添加到查询中。到目前为止,我没有看到任何负面的副作用。我只需要确保从客户端发送(返回)消息已设置所有必需的属性(但这是正常的业务)。

完整的代码:

private void LimitProperties(object entity, List<string> keepProps) {
    if (entity == null)
    {
        return;
    }

    PropertyInfo[] props = entity.GetType().GetProperties();
    foreach (PropertyInfo prop in props)
    {
        if (!keepProps.Contains(prop.Name))
        {
            prop.SetValue(entity, null);
        }
    }
}

public Models.Message GetMessageByID(int messageID) {
    List<string> _validProps = new List<string> { "ID", "Name", "Title" };

    Models.Message message = DbContext.Messages
        .Include(m => m.RefChannel)
        .Include(m => m.RefSender)
        .Include(m => m.RefRecipient)
        .AsNoTracking()
        .FirstOrDefault(m => m.ID == messageID);

    // limit the number of returned fields
    if (message != null)
    {
        LimitProperties(message.RefChannel, _validProps);
        LimitProperties(message.RefSender, _validProps);
        LimitProperties(message.RefRecipient, _validProps);
    }

    return message;
}