public void Delete(string customerId)
{
    using( Mongo mongo = new Mongo(_connectionString) ) {
        mongo.Connect();
        var db = mongo.GetDatabase(_dbName);
        var collection = db.GetCollection<Customer>();        // 从集合中删除指定的对象
        collection.Remove(x => x.CustomerID == customerId);
    }
}
这里的x => x.CustomerID == customerId 
x从哪里冒出来的?mongodb 数据库 对象 方法 

解决方案 »

  1.   

    不是
    private static readonly string _connectionString = "Server=127.0.0.1";private static readonly string _dbName = "MyNorthwind";全局的就这两句话 
      

  2.   

    x => x.CustomerID == customerIdlambda 表达是还能这么写? 受教了.一直以为是 from a select object 的形式.
      

  3.   

    你说的那个东西叫做linq,跟lambda表达式没什么关系,要是不知道lambda 表达式是什么的话可以学,别装作自己好像了解的样子。
      

  4.   

    这是一个普通的 lamda 表达式写法。自从几年前(我相信至少有3、4年了)lamda已经逐步变得普遍了。如果不引用 MongoLinq的dll,只能写collection.Remove(Query.EQ("CustomerID", customerId));这种写法。我猜引用了linq for MongoDB 的dll之后,它一定是使用“扩展方法”方式重载了这个 Remove 方法,使得它也支持以兼容 IQueryable 类型参数的形式,使得可以支持lamda表达式。不过当年我在开始试用 mongodb 的时候,测试过 linq for mongoDb。发现不但有很多bug,而且在许多常见的查询操作上比mongdb.net驱动的原生数据库查询方法慢几十倍,极度困惑并且测试和很久之后(当时已经需要在产品中使用了)不得不放弃 linq for Mongodb,而使用上述原生的查询方式(其实也不费事)。不过就语法来说,linq provoder 为各种数据库提供了非常一致的查询语法机制,尽管你可能觉得“神奇”,但是其实这种lamda表达形式是非常简单的,只要一点linq基础的人都把它当作微风一样地自然。
      

  5.   

    你说的那个东西叫做linq,跟lambda表达式没什么关系,要是不知道lambda 表达式是什么的话可以学,别装作自己好像了解的样子。一直以为是一个东西, 谢谢提醒.
      

  6.   

    Lambda 表达式
    LINQ 查询表达式
      

  7.   

    答:
    因为 静态扩展方法(委托变量)
         因为 委托变量=new委托(Lambda 表达式==匿名方法)
    所以这个x就是参数 
      

  8.   


    x.CustomerID == customerId 那这句话是什么意思呢?
      

  9.   

    return (x.CustomerID == customerId )
      

  10.   

    你确实可以使用“扩展方法”形式在你自己的工程中为类型 MongoCollection<TDefaultDocument> 扩展一个形如public IEnumerable<T> Remove<T>(this MongoCollection<T> recordSet, Func<T,bool> cond)
    {
        .....
    }这样的方法,在这个方法体内,你可以调用 recordSet查找所有对象出来,并且在内存里逐一判断 cond 函数是否返回true,仅返回这些对象!而这里,凡是定义为 Func<T,bool>的函数(输入是一个对象,输出是bool结果)其实都可以用你见到的这个lamda表达式来调用!不过要说的是,这种自己写的简单方法效率太低了。而各种数据库团队写的方法,通常都是 IQueryable 而不是 IEnumerable,因为它们自己要实现表达式解析,并且动态编译(实际上就是执行)转换为数据库原生的查询方法,再查询数据库。也就是说,人家的驱动不是把数据全都读取和反序列到内存里再来过滤的,而是数据库系统本身的机制(可能在本机、可能在其它机器、可能分片到多台机器,总之是直接操作人家底层的内部数据对象)就计算好了,仅仅返回几个符合查询条件的对象,而不是返回所有对象。
      

  11.   


    是否可以理解为 .x 为 collection 对象呢?
      

  12.   

    IEnumerable<T> ,可以理解为这里的一个T差不多吧
      

  13.   

    借这个问题我给你简要距离描述一下lamda表达式的“应用方面的设计”方式。假设你有一个Winform窗口,你想罗列其窗口内所有使用了以“sp”打头的字体的那些控件,你就可以在窗口的某个方法中这样写代码var reuslt = this.FindControls(f => f.Name.StartsWith("sp"));
    当然,这无法编译通过,因为我们只是知道我们有这个需求,还没有写出支持它的接口了。那么你可以添加一个cs文件,内容例如using System;
    using System.Collections.Generic;
    using System.Drawing;
    using System.Windows.Forms;namespace WindowsFormsApplication2
    {
      public static   class Class1
        {      public static  IEnumerable<Control> FindControls(this Form form, Func<FontFamily, bool> condi)
          {
              throw new NotImplementedException();
          }
        }
    }
    再次执行,不但可以编译,而且可以执行!这里我没有去实现FindControls方法内部,这不是重点。这至少说明了,你自己写一个方法,它用来根据调用者提供的 condi 查询条件来查询 form 上的控件,而这个扩展方法可以那样调用(就好像Form类对象原本就有那样的方法定义一样)。这里例子即说明了“扩展方法”的用法,也说明了lamda表达式的用法。
      

  14.   

    嗯,那么命名空间 WindowsFormsApplication2 要改为你自己的winform窗口所用到的命名空间,否则就需要些 using WindowsFormsApplication2;才能让编译器知道Form的扩展方法。总之 lamda 表达式是跟 Func<......> 委托具有姻缘关系,如果你的程序中需要将函数写到变量里将来调用,那么支持了函数,c#编译器就会为你的 lamda 表达式编译为这个函数的实现形式。c#确实很酷。
      

  15.   

    嗯,我把那个扩展方法再多写两行using System;
    using System.Collections.Generic;
    using System.Drawing;
    using System.Drawing.Text;
    using System.Windows.Forms;
    using System.Linq;namespace WindowsFormsApplication2
    {
        public static class Class1
        {        public static IEnumerable<Control> FindControls(this Form form, Func<FontFamily, bool> condi)
            {
                var 用户需要的字符 = (from f in new InstalledFontCollection().Families
                               where condi(f)
                               select f).ToList();            throw new NotImplementedException("尚未实现遍历控件的代码。");
            }
        }
    }你就能看出Func<....>使用方法。
      

  16.   


    是否可以理解为 .x 为 collection 对象呢?
    x一般可以理解为 collection 中的一个元素,有些地方可能跟他还没什么关系
      

  17.   


    x.CustomerID == customerId 那这句话是什么意思呢?我之前用过一段时间的Lambda 表达式 ,我的理解就是x是一个匿名方法(函数)的参数,这个参数的类型应该是一个实体类型(Customer类)吧。
      

  18.   

    然后在Customer类定义了很多属性,如CustomerID 、CustomerName之类的。
      

  19.   

    所以我猜collection 是一个类似于list<Customer>吧。,如有说得不对的地方请大家纠正
      

  20.   


    按说它不但要兼容 IEnumerable<Customer>,而且其实不是使用它,而是至少要使用更具体的 IQueryable<Customer>。因为实现后者这个接口,才能直接调用.net的linq provider机制,从而自动把自定义的Func<.....>函数编织入表达式树中,从而借用linq provider技术来自动转换为调用底层原生数据库查询语句。
      

  21.   

    嗯,看了一下,MongoCollection<TDefaultDocument>并没有支持Linq。我猜这十有八九是linq for MongoDB里边冲在的Remove方法,所以你要看那个dll中的这个DLL是如何实现的。它可能使用了比Collection更底层的MongoCursor,来实现Linq。我不用linq for mongoDb,所以用不到这个语法。不过我不反对别人用,毕竟MongoDb的c#驱动越来越好了!
      

  22.   


    x.CustomerID == customerId 那这句话是什么意思呢?我之前用过一段时间的Lambda 表达式 ,我的理解就是x是一个匿名方法(函数)的参数,这个参数的类型应该是一个实体类型(Customer类)吧。有时候一个三角的回答比那4个三角的要靠谱很多。
      

  23.   

    这货叫这名啊记下不说我还以为是linq 的 where 语法。。
      

  24.   

    这是lambda的语法,x 只是一个变量名,可能看起来有些奇葩,这也是在Linq加入之后,确实有点违反了C#一向的标准语法,但请理解为变量名就够了,x 表示集合中的一项当然也可以理解为
    List<object> list = new List<object>();
    fortch(object x in list)
    {
        if(x.CustomerID == customerId)
        {
              list.Remove(x);
        }
    }
      

  25.   

    x的类型不可能猜出来,而是要看Remove方法的定义。而这个Remove方法又不是在 MongoCollection<T> 类型的定义中,所以有时候就会感觉有点费劲。我不使用ling for mongoDb,但是我估计是在那里做为扩展方法来设置给 MongoCollection<T>类的。而这个x的定义,你不可能看这个T,也不可能看这个MongoCollection。比如说我举的那个 Form.FindControls扩展方法的例子,参数x就是FontFamily类型。所以这个不能猜,要找到真正的东西。