Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MongoDB LINQ提供程序对名为;id";_Linq_Mongodb_Mongodb .net Driver - Fatal编程技术网

MongoDB LINQ提供程序对名为;id";

MongoDB LINQ提供程序对名为;id";,linq,mongodb,mongodb-.net-driver,Linq,Mongodb,Mongodb .net Driver,以下是Mongo LINQ提供程序失败的JSON文档: {"results": {"text":"@twitterapi http://tinyurl.com/ctrefg", "to_user_id":396524, "to_user":"TwitterAPI", "from_user":"jkoum", "metadata": { "result_type":"popular", "recent_retwe

以下是Mongo LINQ提供程序失败的JSON文档:

{"results":
     {"text":"@twitterapi  http://tinyurl.com/ctrefg",
     "to_user_id":396524,
     "to_user":"TwitterAPI",
     "from_user":"jkoum",
     "metadata":
     {
      "result_type":"popular",
      "recent_retweets": 109
     },
     "id":1478555574, 
     "from_user_id":1833773,
     "iso_language_code":"nl",
     "source":"<a href=\"http://twitter.com/\">twitter<\/a>",
     "profile_image_url":"http://s3.amazonaws.com/twitter_production/profile_images/118412707/2522215727_a5f07da155_b_normal.jpg",
     "created_at":"Wed, 08 Apr 2009 19:22:10 +0000",
     "since_id":0,
     "max_id":1480307926,
     "refresh_url":"?since_id=1480307926&q=%40twitterapi",
     "results_per_page":15,
     "next_page":"?page=2&max_id=1480307926&q=%40twitterapi",
     "completed_in":0.031704,
     "page":1,
     "query":"%40twitterapi"}
}
如果我创建一个“Twitter”集合并保存上面的文档,那么当我使用Mongo LINQ provider查询它时,它会抛出一个FileFormatException异常: “元素“id”与Mongo.Context.Tests.NativeTests+结果类的任何字段或属性都不匹配”

但是,有两种替代解决方案可以解决此问题:

  • 重命名结果“id”字段,例如在JSON文档和结果类中都重命名为“idd”。然后LINQ查询工作
  • 保留“id”字段,但另外向结果类添加一个字段“id”,并用属性[BsonId]标记它。现在,结果类包含“Id”和“Id”字段,但是查询可以工作 我使用MongoAPI查询集合,一切正常,所以我猜这一定是MongoDB LINQ提供程序中的一个bug。嵌套JSON元素中的“id”不应该是保留工作,是吗

    更新:以下是本机API查询执行的结果:

    > db.Twitter.find().limit(1);
    
    { "_id" : ObjectId("50c9d3a4870f4f17e049332b"),
     "results" : { 
        "text" : "@twitterapi  http://tinyurl.com/ctrefg", 
        "to_user_id" : 396524, 
        "to_user" : "TwitterAPI", 
        "from_user" : "jkoum", 
        "metadata" : { "result_type" : "popular", "recent_retweets" : 109 }, 
        "id" : 1478555574, 
        "from_user_id" : 1833773, "
        iso_language_code" : "nl", 
        "source" : "<a href=\"http://twitter.com/\">twitter</a>", 
        "profile_image_url" : "http://s3.amazonaws.com/twitter_production/profile_images/118412707/2522215727_a5f07da155_b_normal.jpg", 
        "created_at" : "Wed, 08 Apr 2009 19:22:10 +0000", 
        "since_id" : 0, 
        "max_id" : 1480307926, 
        "refresh_url" : "?since_id=1480307926&q=%40twitterapi", "results_per_page" : 15,    "next_page" : "?page=2&max_id=1480307926&q=%40twitterapi", 
        "completed_in" : 0.031704, 
        "page" : 1, 
        "query" : "%40twitterapi" 
        } 
    }
    
    >db.Twitter.find().limit(1);
    {“_id”:ObjectId(“50c9d3a4870f4f17e049332b”),
    “结果”:{
    “文本”:“@twitterapi”http://tinyurl.com/ctrefg", 
    “to_user_id”:396524,
    “给用户”:“推特API”,
    “来自用户”:“jkoum”,
    “元数据”:{“结果类型”:“流行”、“最近转发”:109},
    “id”:1478555574,
    来自用户id:1833773
    iso语言代码:“nl”,
    “来源”:“,
    “配置文件\图像\ url”:http://s3.amazonaws.com/twitter_production/profile_images/118412707/2522215727_a5f07da155_b_normal.jpg", 
    “创建时间”:“2009年4月8日星期三19:22:10+0000”,
    “自_id”:0,
    “最大id”:1480307926,
    “刷新url”:?由于id=1480307926&q=%40twitterapi,“每页结果”:15,“下一页”:?第2页最大id=1480307926&q=%40twitterapi”,
    “已完成”:0.031704,
    “页码”:1,
    查询“:“%40twitterapi”
    } 
    }
    
    问题是POCO与JSON不匹配

    您的
    Twitter
    类有一个ID和一个名为results的类
    然而,JSON只是有结果。这就是问题所在

    所以实际上,您绕过了
    Twitter
    类,只是创建了
    Result

    您的JSON应该如下所示:

    {
      _id: ObjectId("50c9c8f3e0ae76405f7d2b5e"), 
      "results": { 
         "text":"@twitterapi  http://tinyurl.com/ctrefg",
         "to_user_id":396524,
         "to_user":"TwitterAPI",
         "from_user":"jkoum",
         "metadata":
         {
          "result_type":"popular",
          "recent_retweets": 109
         },
         "id":1478555574, 
         "from_user_id":1833773,
         "iso_language_code":"nl",
         "source":"<a href=\"http://twitter.com/\">twitter<\/a>",
         "profile_image_url":"http://s3.amazonaws.com/twitter_production/profile_images/118412707/2522215727_a5f07da155_b_normal.jpg",
         "created_at":"Wed, 08 Apr 2009 19:22:10 +0000",
         "since_id":0,
         "max_id":1480307926,
         "refresh_url":"?since_id=1480307926&q=%40twitterapi",
         "results_per_page":15,
         "next_page":"?page=2&max_id=1480307926&q=%40twitterapi",
         "completed_in":0.031704,
         "page":1,
         "query":"%40twitterapi"}
        }
    }
    
    {
    _id:ObjectId(“50c9c8f3e0ae76405f7d2b5e”),
    “结果”:{
    “文本”:“@twitterapi”http://tinyurl.com/ctrefg",
    “to_user_id”:396524,
    “给用户”:“推特API”,
    “来自用户”:“jkoum”,
    “元数据”:
    {
    “结果类型”:“流行”,
    “最近转发”:109
    },
    “id”:1478555574,
    “来自用户id”:1833773,
    “iso语言代码”:“nl”,
    “来源”:“推特”,
    “配置文件\图像\ url”:http://s3.amazonaws.com/twitter_production/profile_images/118412707/2522215727_a5f07da155_b_normal.jpg",
    “创建时间”:“2009年4月8日星期三19:22:10+0000”,
    “自_id”:0,
    “最大id”:1480307926,
    “刷新url”:?因为\u id=1480307926&q=%40twitterapi”,
    “每页结果”:15,
    “下一页”:?第2页最大id=1480307926&q=%40twitterapi”,
    “已完成”:0.031704,
    “页码”:1,
    “查询”:“%40twitterapi”}
    }
    }
    
    编辑


    您的
    results
    实际上是一个嵌入式文档(在当前的POCO模型中),因此您还应该使用[BsonId]标记Result.ID

    MongoDB要求存储在数据库中的每个文档都有一个名为“\u ID”的字段(在根级别)

    C#驱动程序假定类中名为“Id”、“Id”或“#Id”的任何字段都要映射到特殊的“#Id”字段。这是一个惯例,一个可以被推翻的惯例。C#驱动程序不知道您的结果类不打算用作集合的根文档,因此它会找到您的“id”字段并将其映射到数据库中的“#id”

    一种可以重写的方法是更改类中字段的名称(如您所发现的)。然后,您还可以使用[BsonElement]属性将C#字段名(例如“idd”)映射到数据库中实际使用的任何名称(例如“id”)。例如:

    public class Result
    {
        [BsonElement("id")]
        public int idd; // matches "id" in the database
        // other fields
    }
    
    var noIdConventions= new ConventionProfile();
    noIdConventions.SetIdMemberConvention(new NamedIdMemberConvention()); // no names
    BsonClassMap.RegisterConventions(noIdConventions, t => t == typeof(Result));
    
    另一种方法是重写查找类的“Id”成员的约定,以抑制结果类的C#驱动程序的默认行为。您可以通过为结果类注册一个新ConventionProfile来实现这一点。例如:

    public class Result
    {
        [BsonElement("id")]
        public int idd; // matches "id" in the database
        // other fields
    }
    
    var noIdConventions= new ConventionProfile();
    noIdConventions.SetIdMemberConvention(new NamedIdMemberConvention()); // no names
    BsonClassMap.RegisterConventions(noIdConventions, t => t == typeof(Result));
    

    您必须确保在程序的早期,即在映射结果类之前执行此操作。

    谢谢Alex,我起初以为您解释了行为,但后来我查看了MongoDB的内容。忘记原始JSON:它用于插入数据。现在数据被插入,文档有了ObjectId。因此,当我查询集合时,文档的Id被正确地映射到Twitter.Id,并且文档中没有更多的Mongo Id,因此嵌套元素不需要映射任何东西。您能澄清一下“因此嵌套元素不需要映射任何东西”的意思吗?您能发布(例如)db.collection.find()的逐字记录结果吗当然,我刚刚用本机Mongo API调用的结果更新了原始帖子。如您所见,ObjectId附加到外部文档,而不是嵌套的“results”元素。此外,我可以有多个嵌套元素,它们都没有相应的ID;我的问题与上面选择的解决方案中提到的完全一样:我为这个问题创建了一个JIRA票证,因为似乎应该有一种简单的方法来覆盖id到_id的映射,而您不希望这种情况发生。见:谢谢你的澄清。不,我知道它内部是如何工作的。在JIRA票据中,我喜欢为嵌套文档使用BsonNoId属性的替代方案。易于掌握和使用。如果我们考虑约定而不是配置,您是否认为可以默认禁用嵌套类的映射,也就是说,如果一个类是用i定义的