1

I know that MongoDb C# driver doesn't support projections so I searched a little bit and I found that many people uses a mongoCursor to perform such queries, I'm trying to select only specific fields and my code is the following:

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();
} 

I got and custom repository for users on top of that:

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

this is the usage:

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

but I'm getting the fields included in the parameter but also all the Enums,dates and Boolean values that are part of the class User, the values that are string and not included in the field list are null so that's fine

enter image description here

what can I do to avoid that?

4

1 回答 1

2

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

现在,类似于说int,enumboolean值类型,所以它们的值不能是null。所以这严格来说是一个 C# 问题:这些属性根本没有值表明它们不存在。相反,它们假定一个默认值(例如falsebool对于0数字类型)。string另一方面,A是引用类型,因此它可以为 null。

策略

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

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

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

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

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

那么问题来了:为什么要竭尽全力排除某些领域?

于 2013-10-11T07:10:07.133 回答