我没有看到问题/回答超过一年的问题,我确信在那段时间内有很多变化。
如果您在.Net / C#环境(生产中)中使用CouchDB,我想知道您使用的是哪个库,以及您使用它的经历。
我发现那里至少有四个图书馆:Hammock,Relax,Divan和SharpCouch。但是,当我谷歌他们的名字+“CouchDB”时,我发现很少有教程,博客文章,推荐书,文档等。它们似乎也没有二进制版本(所有“拉动源和构建”)。
这些库是否仍然相当新/不成熟?它们是如此简单以至于不需要文档吗?使用CouchDB的.Net开发人员是如此之少,没有人在那个空间谈论它?
感谢您的任何见解。
答案 0 :(得分:3)
所有CouchDB功能都通过HTTP API公开,因此您实际需要的只是一个好的HTTP库和一些错误代码处理。我想这就是你找不到很多CouchDB库的原因:协议/ API很容易让你马上开始。
答案 1 :(得分:0)
可能有些像!
class Program
{
static void Main(string[] args)
{
var sDireccion = @"http://localhost:5984/base_principal/_all_docs";
var client = new WebClient { Credentials = new NetworkCredential("zzz", "zzz + zzz"), Encoding = Encoding.UTF8 };
var sRespuesta = client.DownloadString(sDireccion);
cClaseBase cBase = new cClaseBase();
cBase = JsonConvert.DeserializeObject<cClaseBase>(sRespuesta);
foreach (Row str in cBase.rows)
{
sDireccion = @"http://localhost:5984/base_principal/"+str.id;
sRespuesta = client.DownloadString(sDireccion);
cClaseDetalle cd = new cClaseDetalle();
cd = JsonConvert.DeserializeObject<cClaseDetalle>(sRespuesta);
}
}
答案 2 :(得分:0)
我开发.Net和Java。在.Net中,我确实找不到与我在Java中用于访问bedDb所用的东西类似的东西。在Java中,我使用了一个名为jkniv的库,它是一个轻量级的ORM,它使我可以将同一域映射到关系DBMS,NoSQL以及Cassandra,仅通过动态更改存储在一个或多个XML文件中的查询文件。解析内容。
我在.net中寻找了类似的东西来促进使用CouchDb,但我没有找到它,就像您提到的那样,下载并编译了它们……这并不能使我非常满意。
因此,对于一个个人应用程序项目,我最终从jkniv中得到启发,并创建了一个库 myself ,该库简化了沙发床的使用无需直接在我的代码中处理http请求。它封装了对HTTP请求的处理,甚至允许我分开使用长沙发Db的“查找”命令来制作我的C#代码,从而使其更整洁,更易于理解和维护。
此外,我放置这些命令的XML文件包含基于属性值的动态语法,在这里我可以基于逻辑测试决定是否向命令添加摘要。示例:如果“ Person”对象的“ IsFemale”属性等于true,则将芒果查询代码段添加到“ find”命令中,该命令将发送到couchDb。
此外,这些命令使您可以基于参数对象的属性使用文本分析。示例:命令{“ selector”:{“ name”:{“ $ regex” :: filter}}将参数“:filter”替换为所传递参数的此属性的值。
优点是该库只是一个辅助工具,“ find”和“ view”命令使用ouchDb的本机语法,因此您可以在ouchDb本身上构建查询器,对其进行测试,如果它是您想要的方式,将其填充到XML文件中,提供一个ID并在您的C#代码中引用该ID。
啊,该库已经通过Nuget编译并安装了。
下面是一些示例示例。有关如何配置和使用它的详细说明,请参见Github。
链接:Nuget Package | Github | Example of use
代表文档的类的示例。必须继承自AbstractDocument:
public enum DocType
{
USER,
GROUP
}
public enum Status
{
PRE_ACTIVE, ACTIVE, INACTIVE, LOCKED, PRE_CANCEL, CANCEL
}
/// <summary>
/// The objects that represent a document must inherit from AbstractDocument
/// and set the generic to the type of the object itself. With this, this
/// object must not contain the "_id" and "_rev" properties since the inherited
/// class contains these implementations and the services related to these
/// two attributes.
/// Only the methods mapped with [JsonProperty] attribute will be persisted in the
/// document as well as read and filled in automatically.
/// </summary>
public class User: AbstractDocument<User>
{
[JsonProperty("sourceId")] //Newtonsoft
public String SourceId { get; set; }
[JsonProperty("ownerId")] //Newtonsoft
public String OwnerId { get; set; }
[JsonProperty("name")] //Newtonsoft
public String Name { get; set; }
[JsonProperty("email")] //Newtonsoft
public String Email { get; set; }
[JsonProperty("acctId")] //Newtonsoft
public String AcctId { get; set; }
[JsonProperty("docType")] //Newtonsoft
public DocType DocType { get; set; }
[JsonProperty("status")] //Newtonsoft
public Status Status { get; set; }
[JsonProperty("assetIam")] //Newtonsoft
public String AssetIam { get; set; }
[JsonProperty("serial")] //Newtonsoft
public String Serial { get; set; }
public override string ToString()
{
return $"User data: [SourceID: {SourceId}, OwnerID: {OwnerId}, Name: {Name}, Email: {Email}. AcctId: {AcctId}, docType: {DocType} Type: {TypeDocument}, Status: {Status}, AssetIam: {AssetIam}, Serial: {Serial}]";
}
}
创建一个代表数据库的类,扩展CouchRepository类:
/// <summary>
/// Create a repository to represent the database informed
/// in context.Extend the CouchDb Helper repository and tell
/// the constructor what context will be used for this created repository.
/// </summary>
public class UserRepository: CouchRepository
{
public UserRepository() : base("users-db") { } //users-db is context name defined in appsettings.json
}
添加文档的示例:
User user = createUser("email@email.com");
using (UserRepository db = new UserRepository())
{
var result = db.Insert<User>(user); // add document and return instance changed with operation revision id
Console.WriteLine(result.Revision);
}
更改文档的示例:
using (UserRepository db = new UserRepository())
{
// Load document data by ID
var user = db.Get<User>("email@email.com");
user.Name = user.Name + "::CHANGED";
var result = db.Update<User>(user); // update document and return instance changed with operation revision id
Console.WriteLine(result.Revision);
}
删除文档的示例:
using (UserRepository db = new UserRepository())
{
// Load document data by ID
var user = db.Get<User>("email@email.com");
var result = db.Delete<User>(user); // delete document from database. Return true case sucess or false case not deleted
Console.WriteLine($"Sucesso: {result}");
}
精选文档集合示例:
var sts = new List<String> { "ACTIVE", "LOCKED" }; // param filter
using (UserRepository db = new UserRepository())
{
var query = db.FindOf("list-status", new { id = "OwnerIdloop.user.7", statuses = sts, filterStatus = true});
var users = db.List<User>(query);
}
在上面的代码中使用的xml中通过标识符“ list-status”编写的find命令为:
<find id="list-status">
{
"selector": {
"$and": [
{
"docType": {"$eq": "USER"},
"ownerId": {"$eq": :id }
<if test="filterStatus == true">
, "status": {"$in": :in:statuses }
</if>
}
]
},
"fields": [ "_id", "_rev", "ownerId", "sourceId", "docType", "name", "email","status","acctId","assetIam","serial"]
}
</find>
获取所有类型的文档:
using (UserRepository db = new UserRepository()){
/* The document must contain the 'typeDoc' attribute with the same value as the type entered. */
users = db.GetAllOf<User>(); //Get all doc from type parametized.
}
通过ID获取一份文档:
using (UserRepository db = new UserRepository()){
// Load document data by ID
var user = db.Get<User>("email@email.com");
}