包含返回的实体框架限制属性

本文关键字:属性 框架 实体 返回 包含 | 更新日期: 2023-09-27 18:17:55

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

包含返回的实体框架限制属性

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

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

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

我最终将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;
}