1

我正在测试 LiteDB 数据库,但在更新数据时遇到问题。让我们考虑源代码:

    public class Session
    {
        [BsonId]
        public int Id { get; set; }
        public Guid SessionGuid { get; set; }
        public DateTime Date { get; set; }
        public double TotalAmount { get; set; }

        [BsonRef("paymentInfos")]
        public PaymentInfo PaymentInfos { get; set; }
    }

    public class PaymentInfo
    {
        [BsonId] 
        public int Id { get; set; }
        public string Type { get; set; }
        public double Amount { get; set; }    
    }

_database = new LiteDatabase(databasePath);

var sessions = _database.GetCollection<Session>("sessions");

var sessionId = Guid.NewGuid();
var session = new Session
{
    SessionGuid = sessionId,
    Date = Datetime.Now
};
sessions.Insert(session);


var sessions = _database.GetCollection<Session>("sessions");
var session = sessions.FindOne(x => x.SessionGuid == sessionId);

var paymentInfo = new PaymentInfo
{
    Type = "Coin",
    Amount = 2.0,
};

var paymentInfos = _database.GetCollection<PaymentInfo>("paymentInfos");
paymentInfos.Insert(paymentInfo);

session.PaymentInfos = paymentInfo;
sessions.Update(session);

session = sessions.FindOne(x => x.SessionGuid == sessionId);
var paymentAmount = session.PaymentInfos.Amount;

我原以为 paymentAmount 将是 2.0,但它只有 0。这就像只有 session.PaymentInfos.Id 很好,但所有其他属性都丢失了。我的会话更新有问题吗?也许我错过了什么?

提前致谢。

4

1 回答 1

1

使用集合引用时,您需要Include另一个集合: sessions.Include(x=>x.PaymentInfos).FindOne(x => x.SessionGuid == sessionId)

LiteDb文档描述了您所看到的行为:

如果您不在Include查询中使用,则仅使用 ID 集加载类(所有其他属性将保持默认/空值)。

话虽如此,最好避免使用DbRef. LiteDb 是一个非关系型数据库,因此它受益于与传统 SQL 数据库不同的模式。引用有关 NoSql 最佳实践的Stack Exchange 答案:

NoSQL 数据库设计的合适方法是 DDD(域驱动设计)。对于一些曾经设计 RDBMS 的人来说,NoSql 看起来像 Sql 反模式,在 DDD 的范围内考虑时它更有意义。

当我第一次从 SQL 切换到 LiteDB 时,我开始使用DbRef和分离所有东西的集合。随着时间的推移,我得到了更多非关系性思考的练习,我发现我正在处理的用例(位于 3d 空间中的对象之间的关系)可以通过在对象内部存储信息来更准确地建模,而不是使用单独的集合和DbRef.

于 2019-04-17T17:50:27.140 回答