为什么C#和MongoDB驱动代码连接上了,但是写入失败?
Why is C# and MongoDB Driver code connecting, but failing to Write?
我的开发环境信息如下:
- 微软 Visual Studio 社区 2015
- .NET Framework 4.6
- ASP.NET MVC 程序集System.Web.Mvc 版本=5.2.3.0
- MongoDB.Driver 2.0.1.27
- Mongodb 3.0.6
在我的 C# 应用程序中,我有以下检索 MongoDB 数据库引用的代码:
public class MongoDBConnectionManager {
public IMongoDatabase getMongoDB() {
var client = new MongoClient("mongodb://localhost:27017");
MongoClient(System.Configuration.ConfigurationManager.ConnectionStrings["MongoDB"].ConnectionString);
MongoServer.Create("Server=localhost:27017");
IMongoCollection <BsonDocument> UserDetails = iMgDb.GetCollection<BsonDocument>("Users");
return iMgDb;
}
}
这是代表用户业务实体的 POCO class:
using MongoDB.Bson.Serialization.Attributes;
public class UserModel {
[BsonId]
public int ID { get; set; }
[Required]
[BsonElement]
public string UserName { get; set; }
[Required]
[BsonElement]
public string Password { get; set; }
[Required]
[BsonElement]
public string Email { get; set; }
[BsonElement]
public string PhoneNo { get; set; }
[BsonElement]
public string Address { get; set; }
}
这是使用 Mongo 数据库连接管理器的 DAO C# class Class:
public class DAO {
public async Task<int> insertNewUser(UserModel um) {
MongoDBConnectionManager mgoDBCntMng = new MongoDBConnectionManager();
IMongoDatabase database = mgoDBCntMng.getMongoDB();
IMongoCollection <UserModel> UserDetails = database.GetCollection<UserModel>("Users");
try {
Task getTask = UserDetails.InsertOneAsync(um);
await getTask;
} catch(Exception) {
}
return 0;
}
}
当我 运行 应用程序时,我可以在启动 mongoDB 的 DOS 命令提示符 window 中看到以下信息。如果您查看 Dos 命令提示符的末尾,您会注意到建立了 2 个连接:
C:\Program Files\MongoDB\Server.0\bin>mongod --dbpath ./data/db
2015-09-23T12:23:07.896+0530 I JOURNAL [initandlisten] journal
dir=./data/db\jo
urnal
2015-09-23T12:23:07.900+0530 I JOURNAL [initandlisten] recover : no
journal fil
es present, no recovery needed
2015-09-23T12:23:08.060+0530 I JOURNAL [durability] Durability thread started
2015-09-23T12:23:08.062+0530 I JOURNAL [journal writer] Journal writer thread s
tarted
2015-09-23T12:23:08.283+0530 I CONTROL [initandlisten] MongoDB starting
: pid=1
2936 port=27017 dbpath=./data/db 64-bit host=My-PC
2015-09-23T12:23:08.283+0530 I CONTROL [initandlisten] targetMinOS:
Windows 7/W
indows Server 2008 R2
2015-09-23T12:23:08.284+0530 I CONTROL [initandlisten] db version v3.0.6
2015-09-23T12:23:08.284+0530 I CONTROL [initandlisten] git version:
1ef45a23a4c
5e3480ac919b28afcba3c615488f2
2015-09-23T12:23:08.284+0530 I CONTROL [initandlisten] build info:
windows sys.
getwindowsversion(major=6, minor=1, build=7601, platform=2,
service_pack='Servic
e Pack 1') BOOST_LIB_VERSION=1_49
2015-09-23T12:23:08.285+0530 I CONTROL [initandlisten] allocator:
tcmalloc
2015-09-23T12:23:08.285+0530 I CONTROL [initandlisten] options: {
storage: { db
Path: "./data/db" } }
2015-09-23T12:23:08.321+0530 I NETWORK [initandlisten] waiting for
connections
on port 27017
2015-09-23T12:24:20.326+0530 I NETWORK [initandlisten] connection
accepted from
127.0.0.1:65065 #1 (1 connection now open)
2015-09-23T12:24:22.332+0530 I NETWORK [initandlisten] connection
accepted from
127.0.0.1:65066 #2 (2 connections now open)
我真的很困惑如何解决这个问题。我尝试使用 DOS 命令提示符搜索 MongoDB 错误日志,但没有显示任何错误。
从 MongoDB 客户端使用 DOS 命令提示符,我得到以下信息:
C:\Program Files\MongoDB\Server.0\bin>mongo
MongoDB shell version: 3.0.6
connecting to: test
> use foo
switched to db foo
> db.runCommand( { getLastError: 1, w: 1, wtimeout:5000 } )
{
"connectionId" : 6,
"n" : 0,
"syncMillis" : 0,
"writtenTo" : null,
"err" : null,
"ok" : 1
}
我遇到的问题是执行点运行很顺利,但是写入数据库失败
我在上述代码中使用异步和等待的方式有什么问题?
有人可以告诉我如何解决这个问题吗?
来自 MSDN
The await operator is applied to a task in an asynchronous method to suspend the execution of the method until the awaited task completes. The task represents ongoing work.
所以 await 会挂起或阻塞直到任务完成,所以我们只是创建多个任务并确保在我们认为需要时才等待它,如果您正在处理插入集合?
var tasks = new Task<//return type of UserDetails.InsertOneAsync(um)>[//get collection count here];
var count = 0;
foreach(// iterate collection here)
{
try {
tasks[count] = UserDetails.InsertOneAsync(um); // adds continuations and return back immediately i.e. no blocking
count++;
} catch(Exception) {
}
}
await Task.WhenAll(tasks.ToArray()); // here is where we block all tasks and wait for completion
注意:不完全回答,但会稍微清楚我们在做什么
花了一些时间,但问题是我错误地将 int 基本数据类型用于 UserModel 中的 ID 而不是 ObjectId。
这是 UserModel 的更正代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
using MongoDB.Bson;
using MongoDB.Driver;
using MongoDB.Driver.Linq;
using WebApplication1.Models;
using MongoDB.Bson.Serialization.Attributes;
namespace WebApplication1.Models
{
public class UserModel
{
[BsonId]
public ObjectId ID { get; set; }
[Required]
[BsonElement]
public string UserName { get; set; }
[Required]
[BsonElement]
public string Password { get; set; }
[Required]
[BsonElement]
public string Email { get; set; }
[BsonElement]
public string PhoneNo { get; set; }
[BsonElement]
public string Address { get; set; }
}
}
您的 getMongoDB 函数代码有一些问题:
- 不需要两个连接只用一个
- IMongoClient 用于在Mongo.Driver 2.0.1.17 中获取数据库。无需制作 "MongoServer"
- 不需要在"getMongoDB"函数中获取集合
这里是 "getMongoDB" 函数的代码:
public IMongoDatabase getMongoDB()
{
IMongoClient client = new MongoClient("mongodb://localhost:27017");
var iMgDb = client.GetDatabase("Database Name Here");
return iMgDb;
}
希望这会有所帮助。
我的开发环境信息如下:
- 微软 Visual Studio 社区 2015
- .NET Framework 4.6
- ASP.NET MVC 程序集System.Web.Mvc 版本=5.2.3.0
- MongoDB.Driver 2.0.1.27
- Mongodb 3.0.6
在我的 C# 应用程序中,我有以下检索 MongoDB 数据库引用的代码:
public class MongoDBConnectionManager {
public IMongoDatabase getMongoDB() {
var client = new MongoClient("mongodb://localhost:27017");
MongoClient(System.Configuration.ConfigurationManager.ConnectionStrings["MongoDB"].ConnectionString);
MongoServer.Create("Server=localhost:27017");
IMongoCollection <BsonDocument> UserDetails = iMgDb.GetCollection<BsonDocument>("Users");
return iMgDb;
}
}
这是代表用户业务实体的 POCO class:
using MongoDB.Bson.Serialization.Attributes;
public class UserModel {
[BsonId]
public int ID { get; set; }
[Required]
[BsonElement]
public string UserName { get; set; }
[Required]
[BsonElement]
public string Password { get; set; }
[Required]
[BsonElement]
public string Email { get; set; }
[BsonElement]
public string PhoneNo { get; set; }
[BsonElement]
public string Address { get; set; }
}
这是使用 Mongo 数据库连接管理器的 DAO C# class Class:
public class DAO {
public async Task<int> insertNewUser(UserModel um) {
MongoDBConnectionManager mgoDBCntMng = new MongoDBConnectionManager();
IMongoDatabase database = mgoDBCntMng.getMongoDB();
IMongoCollection <UserModel> UserDetails = database.GetCollection<UserModel>("Users");
try {
Task getTask = UserDetails.InsertOneAsync(um);
await getTask;
} catch(Exception) {
}
return 0;
}
}
当我 运行 应用程序时,我可以在启动 mongoDB 的 DOS 命令提示符 window 中看到以下信息。如果您查看 Dos 命令提示符的末尾,您会注意到建立了 2 个连接:
C:\Program Files\MongoDB\Server.0\bin>mongod --dbpath ./data/db
2015-09-23T12:23:07.896+0530 I JOURNAL [initandlisten] journal
dir=./data/db\jo
urnal
2015-09-23T12:23:07.900+0530 I JOURNAL [initandlisten] recover : no
journal fil
es present, no recovery needed
2015-09-23T12:23:08.060+0530 I JOURNAL [durability] Durability thread started
2015-09-23T12:23:08.062+0530 I JOURNAL [journal writer] Journal writer thread s
tarted
2015-09-23T12:23:08.283+0530 I CONTROL [initandlisten] MongoDB starting
: pid=1
2936 port=27017 dbpath=./data/db 64-bit host=My-PC
2015-09-23T12:23:08.283+0530 I CONTROL [initandlisten] targetMinOS:
Windows 7/W
indows Server 2008 R2
2015-09-23T12:23:08.284+0530 I CONTROL [initandlisten] db version v3.0.6
2015-09-23T12:23:08.284+0530 I CONTROL [initandlisten] git version:
1ef45a23a4c
5e3480ac919b28afcba3c615488f2
2015-09-23T12:23:08.284+0530 I CONTROL [initandlisten] build info:
windows sys.
getwindowsversion(major=6, minor=1, build=7601, platform=2,
service_pack='Servic
e Pack 1') BOOST_LIB_VERSION=1_49
2015-09-23T12:23:08.285+0530 I CONTROL [initandlisten] allocator:
tcmalloc
2015-09-23T12:23:08.285+0530 I CONTROL [initandlisten] options: {
storage: { db
Path: "./data/db" } }
2015-09-23T12:23:08.321+0530 I NETWORK [initandlisten] waiting for
connections
on port 27017
2015-09-23T12:24:20.326+0530 I NETWORK [initandlisten] connection
accepted from
127.0.0.1:65065 #1 (1 connection now open)
2015-09-23T12:24:22.332+0530 I NETWORK [initandlisten] connection
accepted from
127.0.0.1:65066 #2 (2 connections now open)
我真的很困惑如何解决这个问题。我尝试使用 DOS 命令提示符搜索 MongoDB 错误日志,但没有显示任何错误。 从 MongoDB 客户端使用 DOS 命令提示符,我得到以下信息:
C:\Program Files\MongoDB\Server.0\bin>mongo
MongoDB shell version: 3.0.6
connecting to: test
> use foo
switched to db foo
> db.runCommand( { getLastError: 1, w: 1, wtimeout:5000 } )
{
"connectionId" : 6,
"n" : 0,
"syncMillis" : 0,
"writtenTo" : null,
"err" : null,
"ok" : 1
}
我遇到的问题是执行点运行很顺利,但是写入数据库失败
我在上述代码中使用异步和等待的方式有什么问题?
有人可以告诉我如何解决这个问题吗?
来自 MSDN
The await operator is applied to a task in an asynchronous method to suspend the execution of the method until the awaited task completes. The task represents ongoing work.
所以 await 会挂起或阻塞直到任务完成,所以我们只是创建多个任务并确保在我们认为需要时才等待它,如果您正在处理插入集合?
var tasks = new Task<//return type of UserDetails.InsertOneAsync(um)>[//get collection count here];
var count = 0;
foreach(// iterate collection here)
{
try {
tasks[count] = UserDetails.InsertOneAsync(um); // adds continuations and return back immediately i.e. no blocking
count++;
} catch(Exception) {
}
}
await Task.WhenAll(tasks.ToArray()); // here is where we block all tasks and wait for completion
注意:不完全回答,但会稍微清楚我们在做什么
花了一些时间,但问题是我错误地将 int 基本数据类型用于 UserModel 中的 ID 而不是 ObjectId。
这是 UserModel 的更正代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
using MongoDB.Bson;
using MongoDB.Driver;
using MongoDB.Driver.Linq;
using WebApplication1.Models;
using MongoDB.Bson.Serialization.Attributes;
namespace WebApplication1.Models
{
public class UserModel
{
[BsonId]
public ObjectId ID { get; set; }
[Required]
[BsonElement]
public string UserName { get; set; }
[Required]
[BsonElement]
public string Password { get; set; }
[Required]
[BsonElement]
public string Email { get; set; }
[BsonElement]
public string PhoneNo { get; set; }
[BsonElement]
public string Address { get; set; }
}
}
您的 getMongoDB 函数代码有一些问题:
- 不需要两个连接只用一个
- IMongoClient 用于在Mongo.Driver 2.0.1.17 中获取数据库。无需制作 "MongoServer"
- 不需要在"getMongoDB"函数中获取集合
这里是 "getMongoDB" 函数的代码:
public IMongoDatabase getMongoDB()
{
IMongoClient client = new MongoClient("mongodb://localhost:27017");
var iMgDb = client.GetDatabase("Database Name Here");
return iMgDb;
}
希望这会有所帮助。