MongoDB 使用 Criteria 排除键 C#

Posted

技术标签:

【中文标题】MongoDB 使用 Criteria 排除键 C#【英文标题】:MongoDB Exclude key C# using Criteria 【发布时间】:2013-04-08 21:11:09 【问题描述】:

所以,我一直在使用这个对象

public class OrdenCompra
    
        public String Proveedor  get; set; 
        public String EmitidaPor  get; set; 
        public String NumOrden  get; set; 
        public String TipoPago  get; set; 
        public String Descuento  get; set; 
        public String Recargo  get; set; 
        public String Observacion  get; set; 
        public List<DetalleOrden> Detalle  get; set; 

        public ObjectId Id  get; set; 
        public OrdenCompra()  this.Id = ObjectId.GenerateNewId(); 
        public OrdenCompra(ObjectId id)  this.Id = id; 
    

我可以使用常规的对象,在我的应用程序中没有问题,但我需要将所有数据导出到 html 文件,如报告。

制作一个 html 标记并使用 jQuery 将 json 文件中的所有数据放到 html 中。

我只是使用常规方式调用它

public String JsongetOrdenCompra(String orden)
        
            try
            
                return this._Collection.FindOneAs<OrdenCompra>(Query.EQ("NumOrden", orden)).ToJson();
            
            catch (Exception e)
            
                throw new Exception("Error al obtener Orden de Compra. \n"+e.Message);
            
        

问题是“_id”键,所以json看起来像

"key":"value", "bla":"bla", "_id" : ObjectId("516d3f86a3e2c814ac7ca180")

所以我无法解析它...

我知道有 SetFields(Exclude("_id")) 方式,但我不能使用 FindOneAs ...

谢谢!

【问题讨论】:

为什么要排除 id? C# 驱动程序会自动将 Bson 中的 _id 字段映射到您的 Id 属性,所以这应该不是问题吗?你能更具体地描述一下这个问题吗? @mnemosyn 问题是“_id”键,所以json看起来像“key”:“value”,“bla”:“bla”,“_id”:ObjectId( "516d3f86a3e2c814ac7ca180") 所以我无法解析它... 您在哪里尝试解析 JSON?为什么不使用实际的 C# 对象?该方法的调用者是什么? @mnemosyn 只是编辑帖子。我需要使用 jQuery 来使用 html 页面中的数据。这就是为什么我要进行从 Object 到 String Json 的转换 FindOneAs 只是 FindAllAs 的包装。整个函数就是这样的:return FindAllAs&lt;TDocument&gt;().SetLimit(1).FirstOrDefault();。 :) 你可以直接调用FindAllAs 并使用SetFields,就像你想要的那样。 【参考方案1】:

MongoDB ToJson 扩展方法的行为有点奇怪 - 它可以配置,但输出往往难以使用。我建议你使用ServiceStack.TextjavascriptSerializer 作为Json 序列化器,像这样:

public string JsongetOrdenCompra(String orden)

    try
    
        var data = this._Collection.FindOneAs<OrdenCompra>(Query.EQ("NumOrden", orden));
        var s = new System.Web.Script.Serialization.JavaScriptSerializer();
        var result = s.Serialize(data);
        return result;
        // Alternatively, ServiceStack.Text.JsSerializer or 
        // extension methods like ASP.NET MVC's Json()
    
    catch (Exception e)
    
        throw new Exception("Error al obtener Orden de Compra. \n"+e.Message);
    

所有这一切都不是最佳实践,因为您将所有数据展示给公众,并且公众与数据库之间没有额外的验证和确认级别。

更好的方法通常是create data transfer objects (DTOs) 并映射数据,例如使用AutoMapper,如下所示:

public class OrdenDTO 

    public String Proveedor  get; set; 
    public String EmitidaPor  get; set; 


public class OrdenReadDTO : OrdenDTO

    public ObjectId Id  get; set; 



...
  var data = this._Collection.FindOneAs<OrdenCompra>(Query.EQ("NumOrden", orden));
  var dto = AutoMapper.Mapper.DynamicMap<OrdenReadDTO>(dto);
  var s = new System.Web.Script.Serialization.JavaScriptSerializer();
  var string = s.Serialize(data);
  return string;

这个想法是OrdenDTO 包含可以发送到服务器的所有信息,OrdenReadDTO 还包含可以从服务器读取的所有数据。通常,ID 是只读的。

如果您使用的是 ASP.NET MVC 或类似框架,通常有一些方法可以处理实际的域对象,如下所示:

public ActionResult JsongetOrdenCompra(String orden)

    // Assuming ASP.NET MVC
    try
    
        var data = this._Collection.FindOneAs<OrdenCompra>(Query.EQ("NumOrden", orden));
        var dto = AutoMapper.Mapper.DynamicMap<OrdenReadDTO>(dto);
        return Json(dto);
    
    catch (Exception e)
    
        throw new Exception("Error al obtener Orden de Compra. \n"+e.Message);
    

【讨论】:

谢谢,这个答案真的很长!我了解了 DTO 方式:) 很长只是因为我复制了代码示例两次 :) 关键是:不同的 json 序列化程序将简单地调用 ToString() 方法,并且 Id 将易于用作字符串(而且它将被命名为Id,而不是_id)。使用 DTO 是可选的,但这是个好主意。 最后,我只使用 DataContractJsonSerializer,它对我来说更容易更短:) 谢谢人 ;D【参考方案2】:

最终使用 C# DataContractJsonSerializer

首先,将 using System.Runtime.Serialization; 添加到您的类(和项目)中。

然后将 [DataMember] 添加到您的所有属性中,例如

[DataMember]
public String Proveedor  get; set; 
[DataMember]
public String EmitidaPor  get; set; 
//and so on

现在在你的控制器上

ClasesProClean.OrdenCompra Orden = HO.getOrdenCompra(orden);
DataContractJsonSerializer serializer =  new DataContractJsonSerializer(Orden.GetType());
System.IO.MemoryStream ms = new System.IO.MemoryStream();
serializer.WriteObject(ms, Orden);
String json = Encoding.Default.GetString(ms.ToArray());

输出:

"Descuento":"5%","Detalle":["Cantidad":60,"CodProveedor":"45AB","Precio":600,"Producto":"Betún","Total":36000,"Cantidad":1000,"CodProveedor":"3D2","Precio":1000,"Producto":"Cera para piso flotante","Total":1000000],"EmitidaPor":"Mario Cares","Id":"_increment":8167808,"_machine":10740424,"_pid":5292,"_timestamp":1366114182,"NumOrden":"45","Observacion":"A la brevedad","Proveedor":"Atilio Di Gianmmarino S.","Recargo":"10%","TipoPago":"Contado"

这就是我一直在寻找的,一个可读的 json ;)

【讨论】:

以上是关于MongoDB 使用 Criteria 排除键 C#的主要内容,如果未能解决你的问题,请参考以下文章

java - 如何在java中查询mongoDb时使用Criteria all?

如何使用 mongoDB 条件查询在 java 中获得更干净的代码 [重复]

mongodb中Criteria转换为es条件

在spring mongodb查询中指定多个标准

MongoDB 更新文档

Spring Data MongoDB - Criteria API OrOperator 无法正常工作