【问题标题】:MongoDB C# Select specific columnsMongoDB C# 选择特定列
【发布时间】:2013-10-11 03:19:09
【问题描述】:

我知道 MongoDb C# 驱动程序不支持投影,所以我搜索了一下,发现很多人使用 mongoCursor 来执行此类查询,我试图仅选择特定字段,我的代码如下:

public T GetSingle<T>(Expression<Func<T, bool>> criteria,params Expression<Func<T, object>>[] fields) where T : class
{
    Collection = GetCollection<T>();
    return Collection.FindAs<T>(Query<T>.Where(criteria)).SetFields(Fields<T>.Include(fields)).SetLimit(1).SingleOrDefault();
} 

除此之外,我还为用户定制了存储库:

public User GetByEmail(string mail, params Expression<Func<User, object>>[] fields)
{
    return GetSingle<User>(x=>x.Email==mail,fields);
}

这是用法:

_repository.GetByEmail(email, x=>x.Id,x=>x.DisplayName,x=>x.ProfilePicture)

但是我得到了包含在参数中的字段,还有属于 User 类的所有枚举、日期和布尔值,作为字符串且未包含在字段列表中的值是 null,所以很好

我能做些什么来避免这种情况?

【问题讨论】:

    标签: mongodb mongodb-.net-driver mongodb-query


    【解决方案1】:

    通过使用SetFields,您可以指定通过线路的内容。但是,在这种情况下,您仍然要求驱动程序返回 TUser 类型的水合对象。

    现在,类似于说intenumbooleanvalue types,所以它们的值不能是null。所以这严格来说是一个 C# 问题:这些属性根本没有值表明它们不存在。相反,它们采用默认值(例如,false 用于 bool0 用于数字类型)。另一方面,stringreference type,因此它可以为空。

    策略

    使属性可以为空您可以在模型中使用可以为空的字段,例如:

    class User {
        public bool? GetMailNotifications { get; set; }
    }
    

    这样,值类型可以具有其有效值之一或null。但是,这可能会很笨拙,因为您必须进行 null 检查并在想要访问该属性时使用 myUser.GetMailNotifications.ValuemyUser.GetMailNotifications.GetValueOrDefault 帮助程序。

    只包含字段这并不能回答如何的问题,但至少有三个很好的理由说明包含它们是个好主意:

    1. 在传递User 对象时,希望该对象处于有效状态。否则,您可能会将部分水合的对象传递给进一步传递它的方法,并且在某些时候,有人尝试进行没有意义的操作,因为该对象不完整
    2. 使用更方便
    3. 性能优势可以忽略不计,除非您要嵌入巨大的数组,我建议无论如何都不要这样做,而这里不是这种情况。

    所以问题是:你为什么要竭尽全力排除某些字段?

    【讨论】:

    • 感谢您的回答,我没有意识到空值的情况,这确实是与 c# 相关的特征(感谢提醒)。为了将整个实体作为用户传递,我只需要以这种方式传递所需的信息,如果应用程序增长,我已经有了一个机制,该机制将只提供在任何情况下(安全、隐私或性能)传递所需的字段问题可能也适用于列表或单个水合对象,我也会更新代码。
    猜你喜欢
    • 1970-01-01
    • 2018-11-03
    • 2015-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-04
    • 2011-02-27
    • 2018-03-17
    相关资源
    最近更新 更多