C# 可查找模型
我目前正在使用C# 可查找模型,c#,mongodb,aggregation-framework,C#,Mongodb,Aggregation Framework,我目前正在使用MongoDB作为数据库进行一个项目,我遇到了一些问题,即如何解决一个模型包含一些外来文档的ID,并在不需要返回到BsonDocument的情况下查找这些ID的问题 最初我有一个(精简的)模型类: public class TestSession { [BsonId] public ObjectId Id { get; set; } [BsonElement("taskId")] public ObjectId? TaskId { get; set
MongoDB
作为数据库进行一个项目,我遇到了一些问题,即如何解决一个模型包含一些外来文档的ID,并在不需要返回到BsonDocument
的情况下查找这些ID的问题
最初我有一个(精简的)模型类:
public class TestSession
{
[BsonId]
public ObjectId Id { get; set; }
[BsonElement("taskId")]
public ObjectId? TaskId { get; set; }
}
有时我需要由TaskId
引用的具体TaskConfiguration
在本例中,我使用
$lookup
来解析它
首先,我引入了一个新成员来保存具体的TaskConfiguration
实例,将我的模型类更改为:
public class TestSession
{
[BsonId]
public ObjectId Id { get; set; }
[BsonElement("taskId")]
public ObjectId? TaskId { get; set; }
[BsonIgnore]
public TaskConfiguration Task { get; set; }
}
然后我意识到聚合无法反序列化查找和解卷的任务
值,我猜是因为BsonIgnore
我找不到任何选项来覆盖它,也找不到任何其他解决方案 最后,我决定将模型类拆分为一个初始类,该类正好包含文档的数据库表示形式,另一个派生类包含已解析的
Task
成员,而不包含BsonIgnore
属性,以便对其进行反序列化
生成的类如下所示:
public class TestSessionModel
{
[BsonId]
public ObjectId Id { get; set; }
[BsonElement("taskId")]
public ObjectId? TaskId { get; set; }
}
public class TestSession : TestSessionModel
{
[BsonElement("task")]
public TaskConfiguration Task { get; set; }
}
虽然这种方法似乎有效,但我现在必须将所有类似的类分开,这不仅可能会创建很多类,而且可能会混淆读者要使用的类。此外,必须小心不要将派生类存储到数据库中
我现在的问题是,在这种情况下,我目前的方法是否是可行的,或者是否有更好/更安全的替代方法?您可以使用
BsonIgnore
方法来实现,但您需要这样预测最终结果:
public class TestSessionModel
{
[BsonId]
public ObjectId Id { get; set; }
[BsonElement("taskId")]
public ObjectId? TaskId { get; set; }
}
public class TestSession : TestSessionModel
{
[BsonElement("task")]
public TaskConfiguration Task { get; set; }
}
var res=collection.AsQueryable()
.Where(t=>t.Id==session.Id)
.加入(
foreignColl.AsQueryable(),//外部集合
s=>s.TaskId,//本地字段
c=>c.Id,//外部字段
(s,c)=>新测试会话//投影
{
Id=s.Id,
Name=s.Name,
TaskId=s.TaskId,
任务=c
})
.Single();
以下是我用于测试的完整程序:
使用MongoDB.Bson;
使用MongoDB.Bson.Serialization.Attributes;
使用MongoDB.Entities;
使用MongoDB.Entities.Core;
使用System.Linq;
命名空间堆栈溢出
{
公共类TestSession:实体
{
公共字符串名称{get;set;}
[BsonRepresentation(BsonType.ObjectId)]
公共字符串TaskID{get;set;}
[b索尼奥雷]
公共任务配置任务{get;set;}
}
公共类任务配置:实体
{
public int NumOfIterations{get;set;}
}
公共静态类程序
{
私有静态void Main()
{
新DB(“测试”);
var task=newtaskconfiguration{NumOfIterations=10};
task.Save();
var session=newtestsession{Name=“这是一个测试会话”,TaskID=task.ID};
session.Save();
var res=DB.Queryable()
.Where(t=>t.ID==session.ID)
.加入(
DB.Queryable(),
s=>s.TaskID,
c=>c.ID,
(s,c)=>新测试会话
{
ID=s.ID,
Name=s.Name,
TaskID=s.TaskID,
任务=c
})
.Single();
}
}
}
是的,这将是另一种解决方案,但如果模型类比示例大得多,这就不起作用了。原始模型类包含大约11个属性,不包括我将用于解析实例的属性。也许我可以将投影代码放在其他地方以供重用,但自动映射解决方案仍然会更好,因为不会有额外的映射代码需要维护/忘记;)“谢谢你的解决方案。”托本吉同意了。这不太理想。如何投影到这样一个匿名类型:(s,c)=>new{Session=s,Task=c})