ServiceStack OrmLite多个相同类型的引用加载

时间:2016-05-03 23:53:16

标签: c# .net servicestack ormlite-servicestack

在我的ServiceStack应用程序中,我实现了一个简单的聊天,其中2个用户可以进行对话。为简单起见,我刚刚创建了一个TextMessages表,其中包含以下字段:

listNew

我的UserAuth继承了基础,并增加了2个字段:

listNew_ = [x + y for x, y in zip(list1, list2)]
# listNew_ = ['1a', '2b', '3c']

现在让我们说我创建了一些用户,然后创建了一些消息:

public class TextMessage
{
    [AutoIncrement]
    [PrimaryKey]
    public int Id { get; set; }

    [References(typeof(MyUserAuth))]
    public int FromUserId { get; set; }

    [References(typeof(MyUserAuth))]
    public int ToUserId { get; set; }

    [Reference]
    [ForeignKey(typeof(MyUserAuth))]
    public MyUserAuth FromUser { get; set; }

    [Reference]
    [ForeignKey(typeof(MyUserAuth))]
    public MyUserAuth ToUser { get; set; }

    //TimeZoneInfo.ConvertTimeToUtc(dateNow);
    public DateTime UtcReceivedOn { get; set; }

    public string Text { get; set; }
}

然后我尝试阅读我的用户:

public class MyUserAuth : UserAuth
{
    public List<TextMessage> TextMessagesAsAuthor { get; set; }

    public List<TextMessage> TextMessagesAsRecipient { get; set; }
}

此处的问题是,用户在var msg1 = new TextMessage { FromUserId = 1, ToUserId = 2, UtcReceivedOn = dt, Text = "Hello" }; var msg2 = new TextMessage { FromUserId = 1, ToUserId = 3, UtcReceivedOn = dt, Text = "Hello" }; var msg3 = new TextMessage { FromUserId = 1, ToUserId = 4, UtcReceivedOn = dt, Text = "Hello" }; var msg4 = new TextMessage { FromUserId = 1, ToUserId = 4, UtcReceivedOn = dt, Text = "Hello" }; var user = db.LoadSingleById<MyUserAuth>(1); 中都有4封邮件,而逻辑上TextMessagesAsAuthor中应为4,TextMessagesAsRecipient中应为0。我如何告诉OrmLite不同这两个属性?

1 个答案:

答案 0 :(得分:6)

OrmLite仅支持您在TextMessage表格中使用的multiple 1:1 Self References,它不支持多个1:M外部参考,例如您尝试申报:

public class MyUserAuth : UserAuth
{
    public List<TextMessage> TextMessagesAsAuthor { get; set; }

    public List<TextMessage> TextMessagesAsRecipient { get; set; }
}
  

另请注意,没有[Reference]属性的复杂属性会被他们所依赖的行包围,这不是您想要的。

也是OrmLite的POCO References only load 1-level deep,即引用不会递归地下载并加载引用的表引用或填充任何周期性的反向引用,这就是你试图做的事情

所以我按原样保留短信:

var msgs = new[]
{
    new TextMessage { FromUserId = 1, ToUserId = 2, Text = "msg #1" }, 
    new TextMessage { FromUserId = 1, ToUserId = 3, Text = "msg #2" }, 
    new TextMessage { FromUserId = 1, ToUserId = 4, Text = "msg #3" }, 
    new TextMessage { FromUserId = 1, ToUserId = 4, Text = "msg #4" }, 
};
db.InsertAll(msgs);

您可以使用它来加载多个自我用户引用,例如:

var msg1 = db.LoadSingleById<TextMessage>(1);
msg1.PrintDump(); //prints populated FromUser/ToUser properties

但是你不能为MyUserAuth多个1:M外部引用做同样的事情。在这种情况下,我仍然会将TextMessage集合添加到MyUserAuth表中,但是您想要在创建MyUserAuth表时告诉OrmLite忽略它们,您可以使用[Ignore]属性,例如:

public class MyUserAuth : UserAuth
{
    [Ignore]
    public List<TextMessage> TextMessagesAsAuthor { get; set; }

    [Ignore]
    public List<TextMessage> TextMessagesAsRecipient { get; set; }
}

然后您可以手动填充它们,即:

var user1 = db.SingleById<MyUserAuth>(1);
user1.TextMessagesAsAuthor = db.Select<TextMessage>(x => x.FromUserId == 1);
user1.TextMessagesAsRecipient = db.Select<TextMessage>(x => x.ToUserId == 1);
user1.PrintDump(); //prints populated MyUserAuth TextMessages