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

Har*_*uck 3 .net c# servicestack ormlite-servicestack

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

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; }
}
Run Code Online (Sandbox Code Playgroud)

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

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

    public List<TextMessage> TextMessagesAsRecipient { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

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

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" };
Run Code Online (Sandbox Code Playgroud)

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

var user = db.LoadSingleById<MyUserAuth>(1);
Run Code Online (Sandbox Code Playgroud)

这里的问题是用户在两者中都有4条消息,TextMessagesAsAuthor而TextMessagesAsRecipient在逻辑上应该有4英寸TextMessagesAsAuthor和0英寸TextMessagesAsRecipient.我如何告诉OrmLite不同这两个属性?

myt*_*thz 6

OrmLite仅支持您在表中使用的多个1:1自引用TextMessage,它不支持多个1:M外部引用,就像您尝试声明的那样:

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

    public List<TextMessage> TextMessagesAsRecipient { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

另请注意,没有[Reference]属性的复杂属性会随着它们所在的行进行blob,这不是您想要的.

此外OrmLite的POCO参考只装1级深,即引用不递归下去并加载引用的表引用,以及或填充任何周期性的反向引用这是它看起来就像你正在试图做的.

所以我会保留原文:

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);
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

    [Ignore]
    public List<TextMessage> TextMessagesAsRecipient { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)