3

我正在使用 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;
}
4

2 回答 2

3

RefSender以这种方式拥有具有某些null值的类型对象风险太大。因为不清楚它是真正的 null还是未加载的 null

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

同样如前所述,在您所说的情况下,一种解决方案是创建一个EntityBase包含Id,Name和的基类Title

于 2013-06-11T13:26:51.447 回答
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;
}
于 2013-07-16T08:27:47.190 回答