【问题标题】:how to create collection (1:n) relation如何创建集合(1:n)关系
【发布时间】:2014-04-21 21:18:11
【问题描述】:

我正在我的 Windows 应用商店应用程序 (WinRT) 中实现 SQLite 数据库。 我想在两个表之间建立关系(1:n) 书 (1) - 第 (n) 章

class Book
{
    [SQLite.AutoIncrement, SQLite.PrimaryKey]
    public int Id { get; set; }
    public String Title { get; set; }
    public String Description { get; set; }
    public String Author { get; set; }
    public List<Chapter> Chapters { get; set; }

    public Book() 
    {
        this.Chapeters = new List<Chapter>();
    }
}

我明白了

-       $exception  {"Don't know about     System.Collections.Generic.List`1[Audioteka.Models.Chapter]"}    System.Exception {System.NotSupportedException}

+       [System.NotSupportedException]  {"Don't know about System.Collections.Generic.List`1[Audioteka.Models.Chapter]"}    System.NotSupportedException

+       Data    {System.Collections.ListDictionaryInternal} System.Collections.IDictionary {System.Collections.ListDictionaryInternal}
    HelpLink    null    string
    HResult -2146233067 int
+       InnerException  null    System.Exception
    Message "Don't know about System.Collections.Generic.List`1[Audioteka.Models.Chapter]"  string

我做错了什么?

【问题讨论】:

  • 错误信息还有更多内容吗?也许是个例外?
  • 此附加信息是我收到的异常消息
  • 我以前从未见过错误消息“不知道 System.Collections.Generic.List`1”。您确定要复制并粘贴确切的错误消息吗?
  • @Bobson 我已经更新了我的消息,并在应用中断后从异常中粘贴了更多内容
  • 我在documentation 中找不到任何表明它完全支持表之间关系的内容。这会让我相信它只能理解直接转换为 SQL 列类型(int/long、float/double/decimal、string 等)的基本值类型。所以我无能为力,也无法指出任何可以提供帮助的东西。

标签: c# sqlite microsoft-metro windows-runtime windows-store-apps


【解决方案1】:

只是为了跟进我的评论并进行更多研究 - SQLite-net 不支持任何无法直接映射到数据库的内容。请参阅here 了解原因:

ORM 能够采用 .NET 类定义并将其转换为 SQL 表定义。 (大多数 ORM 都朝另一个方向发展。)它通过检查类的所有公共属性来做到这一点,并由可用于指定列详细信息的属性辅助。

您可以考虑使用不同的 ORM 来实际访问您的数据(我使用 Vici Coolstorage),如果您正在尝试这样做,或者只是从您的课程中删除 List&lt;Chapters&gt; 并添加一个 BookID Chapters 类的字段。这就是数据库将如何表示它。

为了使用它,您可以将其中之一添加到您的课程中:

List<Chapters> Chapters { 
  get { 
     return db.Query<Chapters> ("select * from Chapters where BookId = ?", this.Id); 
  } 
}

List<Chapters> Chapters { 
  get { 
     return db.Query<Chapters>.Where(b => b.BookId == this.Id); 
  } 
}

这至少可以让您轻松拉出列表,尽管它会很慢,因为每次访问它都会访问数据库。

【讨论】:

  • 好的,但我需要 Book 对象中的章节集合 :) 我看到我应该忽略 ORM 的章节并在拾取对象时手动填充它。嗯,这是 SQLite 的一大缺点:/
  • @Fixus - SQLite-net 可能不是您想要使用的 ORM。它似乎严格用于数据库创建和填充,查询功能是事后才想到的。 SQLite 本身没有问题,但您需要一种不同的方式与之通信。
  • @Fixus - 我还添加了一种填充 Chapters 的方法,尽管这不是处理它的好方法。
  • 你能推荐一些不同的方法吗?在每个教程中,我都遇到过 sqlite-net,这就是我使用它的原因。幸运的是,我可以通过很少的手动工作轻松克服这个问题,所以在这个项目中这不是很大的问题,但我想知道未来更好的解决方案。感谢更新
  • @Fixus - 我使用 Vici Coolstorage(并在我的答案中修复了指向它的链接),但我在设置它时遇到了一些问题。我听说过Catnap 的好消息,this question 总是有各种各样的答案。
【解决方案2】:

看看SQLite-Net Extensions。它通过使用反射在 SQLite-Net 之上提供复杂的关系。

从网站中提取的示例:

public class Stock
{
    [PrimaryKey, AutoIncrement]
    public int Id { get; set; }
    [MaxLength(8)]
    public string Symbol { get; set; }

    [OneToMany]      // One to many relationship with Valuation
    public List<Valuation> Valuations { get; set; }
}

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

    [ForeignKey(typeof(Stock))]     // Specify the foreign key
    public int StockId { get; set; }
    public DateTime Time { get; set; }
    public decimal Price { get; set; }

    [ManyToOne]      // Many to one relationship with Stock
    public Stock Stock { get; set; }
}

【讨论】:

    猜你喜欢
    • 2018-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多