gpt4 book ai didi

c# - 在 Mongodb C# 中使用 AsQueryable 进行过滤 - ExpandoObject

转载 作者:行者123 更新时间:2023-12-04 10:00:11 28 4
gpt4 key购买 nike

我正在尝试使用 AsQueryable 和 LINQ 函数查询 mongodb 数据库。

我当前的数据库结构是我有一些集合,主要是在 C# 中定义的记录,如下所示:

public class Record  
{
[BsonElement("formName")]
public string FormName { get; set; }

[BsonElement("created")]
public DateTime Created { get; set; }

[BsonElement("createdBy")]
public string CreatedBy { get; set; }

[BsonId]
[BsonIgnoreIfDefault]
[BsonRepresentation(BsonType.ObjectId)]
private string InternalId { get; set; }

[BsonElement("recordId")]
[Newtonsoft.Json.JsonProperty("recordId")]
public string Id { get; set; }

[BsonElement("organisationId")]
public string OrganisationId { get; set; }

// TODO: Consider making configurable
private string appName = "MediLog";

[BsonElement("appName")]
public string AppName
{
get { return this.appName; }
set { this.appName = value; }
}

[BsonElement("schemaVersion")]
public int SchemaVersion { get; set; }

[BsonElement("contents")]
public ExpandoObject Contents { get; set; }

[BsonElement("modified")]
public DateTime Modified { get; set; }

[BsonElement("modifiedBy")]
public string ModifiedBy { get; set; }

[BsonElement("majorVersion")]
public int MajorVersion { get; private set; }

[BsonElement("minorVersion")]
public int MinorVersion { get; private set; }

[BsonElement("version")]
public string Version
{
get
{
return (MajorVersion + "." + MinorVersion);
}

set
{
MajorVersion = Convert.ToInt32(value?.Substring(0, value.IndexOf(".", StringComparison.OrdinalIgnoreCase)), CultureInfo.InvariantCulture);
MinorVersion = Convert.ToInt32(value?.Substring(value.IndexOf(".", StringComparison.OrdinalIgnoreCase) + 1), CultureInfo.InvariantCulture);
}
}

}

和你一样,数据主要存放在 Contents这是一个 ExpandoObject这就是我的问题所在。

我正在尝试做这样的事情:
 var collection =
database.GetCollection<Record>("recordData").AsQueryable()
.Where(x => x.Contents.SingleOrDefault(z => z.Key == "dateOfBirth").Value.ToString().Length > 0)
.ToList();

但我得到这个异常(exception):

System.InvalidOperationException
HResult=0x80131509
Message={document}{contents}.SingleOrDefault(z => (z.Key == "dateOfBirth")).Value.ToString().Length 不受支持。

另外,当我尝试:
  var collection1 = database.GetCollection<Record>("recordData").AsQueryable()
.Where(x => (DateTime)(x.Contents.SingleOrDefault(z => z.Key == "dateOfBirth").Value) > DateTime.Now)
.ToList();

我得到这个异常(exception):
System.InvalidOperationException
HResult=0x80131509
Message=Convert({document}{contents}.SingleOrDefault(z => (z.Key == "dateOfBirth")).Value) is not supported.

另外,当我这样做时:
var collection =
database.GetCollection(“recordData”).AsQueryable()
.Where(x => (DateTime)x.Contents.First(z => z.Key == “dateOfBirth”).Value > DateTime.Now ).ToList();

我收到此异常:
System.NotSupportedException: ‘The expression tree is not supported: {document}{contents}’

所以我的问题实际上是如何使用 AsQueryable 和 LINQ 对 ExpandoObject 类型的对象运行查询。

谢谢!

最佳答案

无论你想传递给 .Where()方法是一个需要翻译成MongoDB查询语言的表达式树。 C# 编译器将接受 ExpandoObject的方法如 SingleOrDefault (扩展方法)但是当这种表达式树需要转换为 Mongo 查询时,这将在运行时失败。
ExpandoObject没什么特别的当您使用 MongoDB 时。它必须以某种方式翻译成 BSON 文档(MongoDB 格式),例如下面的代码:

dynamic o = new ExpandoObject();
o.dateOfBith = new DateTime(2000, 1, 1);
r.Contents = o;
col.InsertOne(r);

Blade ExpandoObjectBsonDocument 相同或 Dictionary<string, T>所以它只是变成:
{ "_id" : ObjectId(",,,"), "contents" : { "dateOfBith" : ISODate("2000-01-01T07:00:00Z") } }

在您的数据库中。

知道您可以使用 the dot notation 构建查询.还有一个 StringFieldDefinition您可以使用的类,因为您无法从 ExpandoObject 构建表达式树以强类型方式:
var fieldDef = new StringFieldDefinition<Record, DateTime>("contents.dateOfBith");
var filter = Builders<Record>.Filter.Gt(fieldDef, new DateTime(2000, 1, 1));

var res = col.Find(filter).ToList();

关于c# - 在 Mongodb C# 中使用 AsQueryable 进行过滤 - ExpandoObject,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61851443/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com