Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C#中处理SQLite-作为命令推进传递字符串操作_C#_Sqlite_System.data.sqlite - Fatal编程技术网

在C#中处理SQLite-作为命令推进传递字符串操作

在C#中处理SQLite-作为命令推进传递字符串操作,c#,sqlite,system.data.sqlite,C#,Sqlite,System.data.sqlite,我正在我的应用程序中使用SQLite(通过System.Data.SQLite包)。现在,所有插入、查询和其他操作都是通过使用字符串发送命令来完成的,例如: SQLiteCommand command = new SQLiteCommand(comStr, db); 其中comStr-是一个包含命令的字符串变量 还有其他选项可以替代字符串吗?或者字符串是处理.NET SQL查询时应该使用的正确方法吗 问题是使用字符串会变得相当混乱,例如,我有一些用户可以设置的过滤器。使用字符串

我正在我的应用程序中使用SQLite(通过System.Data.SQLite包)。现在,所有插入、查询和其他操作都是通过使用字符串发送命令来完成的,例如:

        SQLiteCommand command = new SQLiteCommand(comStr, db);
其中comStr-是一个包含命令的字符串变量

还有其他选项可以替代字符串吗?或者字符串是处理.NET SQL查询时应该使用的正确方法吗

问题是使用字符串会变得相当混乱,例如,我有一些用户可以设置的过滤器。使用字符串操作命令-虽然有效-我觉得非常脆弱:

    public string GetFilterString()
    {
        string fil1 = "";
        string fil2 = "";
        string fil3 = "";
        string fil4 = "";

        // filter by time
        switch (WithinTimeBtnStatus)
        {
            case WithinTime.All:
                break;
            case WithinTime.Hour:
                string minusHour = (DateTime.Now - new TimeSpan(0, 1, 0, 0)).ToString("yyyy-MM-dd HH:mm:ss.fff");
                fil1 = $" timestamp >= datetime('{minusHour}')";
                break;
            case WithinTime.Day:
                string minusDay = (DateTime.Now - new TimeSpan(1, 0, 0, 0)).ToString("yyyy-MM-dd HH:mm:ss.fff");
                fil1 = $" timestamp >= datetime('{minusDay}')";
                break;
            case WithinTime.Week:
                string minusWeek = (DateTime.Now - new TimeSpan(7, 0, 0, 0)).ToString("yyyy-MM-dd HH:mm:ss.fff");
                fil1 = $" timestamp >= datetime('{minusWeek}')";
                break;
        }

        // filter by extension
        for (int i = 0; i < FilteredExt.Count; i++)
        {
            fil2 += " ext != '" + FilteredExt[i] + "'";
            if (i < FilteredExt.Count - 1)
                fil2 += " and";
        }

        // filter by process
        if (_processFilterSelected.ToLower() != "all" && _processFilterSelected != "")
        {
            fil3 = $" proc == '{_processFilterSelected}'";
        }

        // filter by File Operation
        if (_FileOperationFilterSelected.ToLower() != "all" && _FileOperationFilterSelected != "")
        {
            FileOperation fo = Converters.StringToFileOperation(_FileOperationFilterSelected);
            switch (fo)
            {
                case FileOperation.Deleted:
                    fil4 = " oper == 'DELETED'";
                    break;
                case FileOperation.Renamed:
                    fil4 = " oper == 'RENAMED'";
                    break;
                case FileOperation.Modified:
                    fil4 = " oper == 'MODIFIED'";
                    break;
            }
        }


        string fil = "";
        var tmp = new[] { fil1, fil2, fil3, fil4 };
        foreach (var t in tmp)
        {
            if (t != "")
            {
                fil += " and" + t;
            }
        }

        return fil;
    }
公共字符串GetFilterString()
{
字符串fil1=“”;
字符串fil2=“”;
字符串fil3=“”;
字符串fil4=“”;
//按时间过滤
开关(带INTIMEBTNSTATUS)
{
案例与时间。全部:
打破
案例时间:小时:
字符串minusHour=(DateTime.Now-newtimespan(0,1,0,0)).ToString(“yyyy-MM-dd-HH:MM:ss.fff”);
fil1=$“timestamp>=datetime('{minusHour}')”;
打破
时间内的案例。日期:
字符串minusDay=(DateTime.Now-new TimeSpan(1,0,0,0)).ToString(“yyy-MM-dd-HH:MM:ss.fff”);
fil1=$“timestamp>=datetime('{minusDay}')”;
打破
一周内的案例:
字符串minusWeek=(DateTime.Now-newtimespan(7,0,0,0)).ToString(“yyyy-MM-dd-HH:MM:ss.fff”);
fil1=$“timestamp>=datetime('{minusWeek}')”;
打破
}
//扩展过滤
for(int i=0;i
编辑以提供答案中的一些解决方案

本教程向您展示如何正确实现SQLite并使用Linq扩展与数据库表交互。我已经复制了下面的相关部分。一旦打开数据库连接并创建了数据优先表,就可以像使用Linq处理任何IEnumerable一样与该表交互。它还提供了一个将SQL作为字符串传递的选项,但是由于在编译时没有检查该选项,因此您可能会遇到运行时错误

TodoItemDatabase构造函数如下所示:

public TodoItemDatabase(string dbPath)
{
  database = new SQLiteAsyncConnection(dbPath);
  database.CreateTableAsync<TodoItem>().Wait();
}
公共TodoItemDatabase(字符串dbPath) { 数据库=新的SQLiteAsyncConnection(dbPath); database.CreateTableAsync().Wait(); } 这种方法创建一个在应用程序运行时保持打开状态的数据库连接,因此避免了每次执行数据库操作时打开和关闭数据库文件的开销。 TodoItemDatabase类的其余部分包含跨平台运行的SQLite查询。下面显示了示例查询代码(有关语法的更多详细信息,请参阅Using SQLite.NET文章):

public任务GetItemsAsync()
{
返回database.Table().ToListAsync();
}
公共任务GetItemsNotoneAsync()
{
返回database.QueryAsync(“从[TodoItem]中选择*,其中[Done]=0”);
}
公共任务GetItemAsync(int id)
{
返回database.Table().Where(i=>i.ID==ID).FirstOrDefaultAsync();
}
公共任务SaveItemAsync(TodoItem项)
{
如果(item.ID!=0)
{
返回数据库.UpdateAsync(项);
}
否则{
返回数据库.InsertAsync(项);
}
}
公共任务DeleteItemAsync(TodoItem项)
{
返回database.DeleteAsync(项);
}

因为我没有得到满意的答案,所以我将公布我最终做了什么。我认为这可能是一个不错的方法,但可能还有其他更好的方法来实现我所寻找的(在我的数据库上使用LINQ类型语法,而不是使用包含查询的字符串)

另外,我不确定这是否比简单使用查询字符串更快

TL;DR:使用SQLite.CodeFirst+EntityFramework

(另一方面,可以使用LINQ to SQL而不是EntityFramework,但不确定是否也使用CodeFirst方法。在我尝试和测试此方法后将进行更新)


首先,您需要添加以下软件包:

  • 实体框架
  • System.Data.SQLite(可能还会安装:)
  • System.Data.SQLite.Core
  • System.Data.SQLite.EF6
  • System.Data.SQLite.Linq
最后,如果您是从代码开始(像我一样),您还需要

  • SQLite.CodeFirst
接下来要做的是在app.config中设置连接字符串

(另一方面,在指定提供程序时似乎存在大量错误,卸载和重新安装上述软件包似乎可以解决这些问题。我不太确定删除和重新安装软件包背后的逻辑。)
public Task<List<TodoItem>> GetItemsAsync()
{
  return database.Table<TodoItem>().ToListAsync();
}

public Task<List<TodoItem>> GetItemsNotDoneAsync()
{
  return database.QueryAsync<TodoItem>("SELECT * FROM [TodoItem] WHERE [Done] = 0");
}

public Task<TodoItem> GetItemAsync(int id)
{
  return database.Table<TodoItem>().Where(i => i.ID == id).FirstOrDefaultAsync();
}

public Task<int> SaveItemAsync(TodoItem item)
{
  if (item.ID != 0)
  {
    return database.UpdateAsync(item);
  }
  else {
    return database.InsertAsync(item);
  }
}

public Task<int> DeleteItemAsync(TodoItem item)
{
  return database.DeleteAsync(item);
}
<system.data>
   <DbProviderFactories>
      <remove invariant="System.Data.SQLite.EF6" />
      <add name="SQLite Data Provider (Entity Framework 6)" invariant="System.Data.SQLite.EF6" description=".NET Framework Data Provider for SQLite (Entity Framework 6)" type="System.Data.SQLite.EF6.SQLiteProviderFactory, System.Data.SQLite.EF6" />
      <remove invariant="System.Data.SQLite" />
      <add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".NET Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite" />
   </DbProviderFactories>
</system.data>

<entityFramework>
  <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
      <provider invariantName="System.Data.SQLite.EF6" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" />
      <provider invariantName="System.Data.SQLite" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6"/>
     </providers>
  </entityFramework>
<connectionStrings>
  <add name="YourModel" connectionString="Data Source=|DataDirectory|\NameOfYourDBFile.sqlite" providerName="System.Data.SQLite" />
</connectionStrings>
class YourModel : DbContext
{
    // Your context has been configured to use a 'YourModel' connection string from your application's 
    // configuration file (App.config or Web.config). By default, this connection string targets the 
    // 'YourProject.YourModel' database on your LocalDb instance. 
    // 
    // If you wish to target a different database and/or database provider, modify the 'YourModel' 
    // connection string in the application configuration file.
    public YourModel()
        : base("name=YourModel")
    {
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        var sqliteConnectionInitializer = new SqliteCreateDatabaseIfNotExists<YourModel>(modelBuilder);
        Database.SetInitializer(sqliteConnectionInitializer);
        Database.SetInitializer(new SqliteDropCreateDatabaseWhenModelChanges<YourModel>(modelBuilder));
    }

    // Add a DbSet for each entity type that you want to include in your model. For more information 
    // on configuring and using a Code First model, see http://go.microsoft.com/fwlink/?LinkId=390109.

    public virtual DbSet<YourTableClass> YourTable { get; set; }
}

[Table("YourTable")]
public class YourTableClass
{
    [Key]
    public string Id { get; set; }
    [Required]
    public FileOperation Oper { get; set; }
    [Required, Index]
    public OperationState State { get; set; }
    [Index]
    public string Proc { get; set; }
    [Required]
    public string Src { get; set; }
    public DateTime Timestamp { get; set; }
    // etc.
}
AppDomain.CurrentDomain.SetData("DataDirectory", @"the\path\you\desire");
using (var context = new YourModel())
{
     // some query
}
using (var context = new YourModel())
{
     var t = context.YourTable
       .Where(e => e.State == OperationState.BackedUp)
       .Select(e => e.Proc)
       .Distinct()
 }
using (var context = new YourModel())
{
    var e = context.YourTable.Create();
    e.Id = guid;
    // ...etc
    e.Timestamp = timestamp;
    context.YourTable.Add(e);
    context.SaveChanges();
}
using (var context = new YourModel())
{
    context.Database.ExecuteSqlCommand(comString);
}
    public static IQueryable<YourTable> GetFilteredQueryable(IQueryable<YourTable> yourTable)
    {
        // filter by time
        switch (RestoreLogic.WithinTimeBtnStatus)
        {
            case WithinTime.All:
                break;
            case WithinTime.Hour:
                DateTime offsetHour = DateTime.Now.Add(new TimeSpan(-1, 0, 0));
                yourTable = yourTable.Where(e => e.Timestamp >= offsetHour);
                break;
           // etc.
        }

        // filter by extension
        foreach (var i in FilteredExt)
        {
            yourTable = yourTable.Where(e => e.Ext != i);
        }

        // etc.

        return yourTable;
    }