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})