MongoDB C#UpdateBuilder不会忽略set上的null

时间:2018-05-11 01:02:06

标签: c# mongodb reflection

我有以下两个用户设置首选项的类。用户可能没有任何偏好,只有喜欢,只有不喜欢或两者兼而有之。为简单起见,我在本例中简化了用户模型。

[BsonIgnoreExtraElements]
public class User : Base
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    [BsonIgnoreIfNull]
    public UserPreferences Preferences { get; set; }
}

[BsonIgnoreExtraElements]
public class UserPreferences
{
    [BsonIgnoreIfNull]
    public List<string> Likes { get; set; }
    [BsonIgnoreIfNull]
    public List<string> Dislikes { get; set; }
}

我有一个帮助函数,它使用反射来构造UpdateBuilder。当给定用户对象时,它为非空字段设置一个值,因为我不想具体写出哪些字段已在呼叫上更新。但是,在我目前的情况下,辅助函数失败了。

    public override User Update(User model)
    {

        var builder = Builders<User>.Update.Set(x => x.Id, model.Id);

        foreach(PropertyInfo prop in model.GetType().GetProperties())
        {
            var value = model.GetType().GetProperty(prop.Name).GetValue(model, null);

            if ((prop.Name != "Id") & (value != null))
            {
                builder = builder.Set(prop.Name, value);
            }
        }

        var filter = Builders<User>.Filter;
        var filter_def = filter.Eq(x => x.Id, model.Id);

        Connection.Update(filter_def, builder);

        return model;

    } 

问题:仅向Preferences提供Likes或仅提供Dislikes时,它会在MongoDB中将其他属性设为null。

期望的结果:如果列表为null,我希望MongoDB忽略LikesDislikes属性,就像我的代码中的其他属性一样。

1 个答案:

答案 0 :(得分:0)

我认为最好的方法是如果该字段的值为空,则取消设置该字段

public override User Update(User model)
{

    var builder = Builders<User>.Update.Set(x => x.Id, model.Id);

    foreach(PropertyInfo prop in model.GetType().GetProperties())
    {
        var value = model.GetType().GetProperty(prop.Name).GetValue(model, null);

        if (prop.Name != "Id")
        {
           if(value != null)
           {
                builder = builder.Set(prop.Name, value);
           }
           else
           {
                builder = builder.Unset(prop.Name);
           }
            
        }
    }

    var filter = Builders<User>.Filter;
    var filter_def = filter.Eq(x => x.Id, model.Id);

    Connection.Update(filter_def, builder);

    return model;

} 

我希望这能解决您的问题