【问题标题】:using SQLite inside portable class library在可移植类库中使用 SQLite
【发布时间】:2012-11-21 21:08:02
【问题描述】:

最近我们开始着手一个新项目,其中包括 Windows 8 Metro、Windows Phone 和桌面应用程序的客户端。决定使用 MVVM 模式作为主要架构,因为在项目之间共享 ViewModel 对我们来说是更容易接受的解决方案。

我们决定为此目的使用可移植类库,但问题是在从 Visualstudio 2012 扩展库下载并安装 SQLite for Windows 运行时后,当我们尝试添加对适当库的引用时,我们根本看不到这些库。这让我们想到,在 Portable 类库项目中使用 SQLite 是不可能的。

也许你们中的一些人已经这样做并且知道我们可以实现该功能的方式?请为我们提供开发此任务的正确方法,因为在此开发阶段使用 SQLite 和具有可重用代码非常重要

【问题讨论】:

  • SQLite 不能在可移植类库项目中使用。
  • ?你能再解释一下吗?必须有使用它的方法。例如,可以编写包装器接口并使用 IoC 或 DI 来提供它。 StackOverflow 用户还有其他建议吗?
  • 我认为您不能从可移植类库中引用“本机”DLL,例如 SQLite。但是,请查看 SQLite 的 C# 端口,csharp-sqlite。没有 PCL 项目,但有针对所有感兴趣平台的专用项目。您可以为特定平台引用 csharp-sqlite DLL,或者您可以检查为 csharp-sqlite 创建 PCL 的工作量。
  • 好吧,csharo-sqlite 似乎是我们任务的某种解决方案,但是如果我们在 PCL 项目中创建 IRepositori 接口并在不同的项目中实现它,你不认为我会更好吗项目?与使用构造函数注入相比,我们将使用 SQLite 将具体实现传递给我们的可移植类库 Service 类。这行得通吗?我认为这将是更干净和可维护的方式。我说的对吗?

标签: c# sqlite windows-8 windows-phone-8 portable-class-library


【解决方案1】:

在 MvvmCross 中,我们通过不同的方法解决了这个问题。

我们想利用 SQLite 的本地端口,并且我们想使用来自https://github.com/praeclarum/sqlite-net/ 的 SQLite-net ORM 包装器

因此,我们不只是使用 PCL,而是:


在代码级别,客户端应用可以像这样使用插件:

在业务逻辑库(PCL 或特定平台)中,代码可以定义模型对象:

public class ListItem
{
    [PrimaryKey, AutoIncrement]
    public int Id { get; set; }
    public string Name { get; set; }
    public string WhenCreated { get; set; }
}

在启动过程中应用可以调用:

  Cirrious.MvvmCross.Plugins.Sqlite.PluginLoader.Instance.EnsureLoaded();
  var factory = this.GetService<ISQLiteConnectionFactory>();
  var connection = factory.Create("SimpleList");
  connection.CreateTable<ListItem>();

然后在运行过程中,代码可以做如下事情:

  connection.Insert(new ListItem() { Name = TextToAdd, WhenCreated = DateTime.Now.ToString("HH:mm:ss ddd MMM yyyy") });

 public ListItem this[int index]
 {
     get { return _connection.Table<ListItem>().OrderBy(_sortOrder).Skip(index).FirstOrDefault(); }
 }

而特定于 UI 的代码必须引用插件的特定于平台的扩展并将该平台特定的实现注入到 IoC/DI 系统中。在 Droid 上这确实很简单(因为 MonoDroid 在运行时支持 Assembly.Load),但在其他平台上,这涉及到一些“样板”代码,例如:

    protected override void AddPluginsLoaders(Cirrious.MvvmCross.Platform.MvxLoaderPluginRegistry loaders)
    {
        loaders.AddConventionalPlugin<Cirrious.MvvmCross.Plugins.Sqlite.WinRT.Plugin>();
        base.AddPluginsLoaders(loaders);
    }

注意事项:

【讨论】:

  • 该方法非常接近我们的想法,但非常感谢您提供这些链接,因为这些链接对我们的开发过程非常有帮助,我认为这确实是解决我们问题的完美解决方案是一个单独的问题,但你知道是否可以在 PCL 中使用 Task ?我没能成功
  • 这是一个很好的问题 - 将其作为一个新问题提出来,您会得到答案!
  • @rati_ge 如果您的目标平台已经有 Task,那么它应该在您的 PCL 中可用。可能您的目标是 Windows Phone 7.5,它不支持任务。但是,我们已经发布了一个包,它在各种平台上支持 Task 和 async/await。请参阅此博客文章:blogs.msdn.com/b/bclteam/archive/2012/10/22/…
  • @DanielPlaisted 感谢您的回答,我们发现,我们的目标是 Silverlight 4,这是我们更改目标选项后的问题 Task 现在可用,但很高兴知道WP 7.5 也有解决方案
  • 我本来打算用同样的方法,但是我的PCL里面好像不能安装sqlite-net,这意味着我不能使用像[PrimaryKey]这样的属性来装饰我的模型。仅在我的存储库的具体实现中拥有这些属性并没有帮助,因为模型应该在 PCL 中。您是如何解决这个问题的?
【解决方案2】:

Stuart 很好地解释了如何使用 SQLite 创建 PCL,但今天我发现了这种方法,我希望它能更好地解决任何其他问题

New open source Portable Class Library for SQLite

【讨论】:

【解决方案3】:

可能值得一提的是 AutoIncrement 和 PrimaryKey 属性来自以下命名空间

使用 Cirrious.MvvmCross.Plugins.Sqlite;

  public class Reference : IBusinessEntity

    {

      public string Key { get; set; }

      public string Value { get; set; }



     [PrimaryKey, AutoIncrement]

      public long Id { get; set; }

  }

【讨论】:

    【解决方案4】:

    经过数周的搜寻,我终于认为您必须使用以下方式进行连接:

    var factory = new MvxWpfSqLiteConnectionFactory();
    

    我安装了

    using Cirrious.MvvmCross.Community.Plugins.Sqlite;
    using Cirrious.MvvmCross.Community.Plugins.Sqlite.Wpf;
    using Cirrious.CrossCore;
    

    对于所有 MVVMcross 天才和所有 Sqlite 天才来说,这可能是显而易见的。

    没有人在任何地方提到这一点,并且 MVVMcross 的示例在实际进行连接时都不会编译或使用与 MVVM 或 PCL 不兼容的 Sqlite.NET。

    哦,这适用于 Winforms、PCL 等(我什至不使用 Wpf)。

    【讨论】:

    • 我仍然无法获得带有索引的“get { return _connection.Table(); }”,或者插入工作。谁能帮我解决这个问题?
    • 我的错,它有效。您需要多个条目才能使 Skip 工作,并且 Insert 就可以了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-15
    相关资源
    最近更新 更多