.Net EntityFramework Core - SQLite Error 1: no such table - sqlite

I am running into an issue where the code is unable to find my existing Sqlite database that is in the same folder as this code that is calling it. The error I am getting is, "SQLite Error 1 table does not exist." I know the table exists, it is just unable to find the path. What am I doing wrong?
Note: I am not creating a code first Sqlite database. This is opening an existing Sqlite database
DATABASE CONTEXT CODE
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MyWidget.Domain.Data
{
public static class MyWidgetService
{
public static void GetAll()
{
using var context = new MyWidgetContext();
if (context.Translations.Any())
{
var data = context.Widgets.ToList();
foreach (var widget in data)
{
Console.WriteLine(widget.ProductName);
}
}
else
{
Console.WriteLine("No widgets found");
}
}
}
}
**DATABASE SERVICE CODE
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Text;
using Microsoft.EntityFrameworkCore;
namespace MyWidget.Domain.Data
{
public class MyWidgetContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlite(connectionString: "Filename=./MyWidgetDB.db");
}
public DbSet<WidgetData> Widgets { get; set; }
}
public class WidgetData
{
public int Id { get; set; }
public string ProductName { get; set; }
}
}

I decided to go another direction and use Dapper and System.Data.Sqlite.Core. This video by Tim Corey perfectly explains how to implement it:
https://www.youtube.com/watch?v=ayp3tHEkRc0
This methodology works really well and am using it in my GitHub project:
https://github.com/encouragingapps/Blender3DReference

I had the same problem: SqliteException: SQLite Error 1: 'no such table: ScanFolders'. I used the SQLlite Browser to inspect the database in the debug folder and it had no tables. Checking the properties on the db was set to "Do Not Copy" I changed it to "Copy if Newer" and that fixed the issue for me.

Related

Creating table Entity Framework Core and SQLite

Using Microsoft.EntityFrameworkCore.SQLite, I'm attempting to create a code level creation of a database, and add a simple row to a table. I get the error, SQLite error: no such table Jumplists.
From last to first, here are the classes
using JumpList_To_Clipboard.Data.Tables;
using Microsoft.EntityFrameworkCore;
namespace JumpList_To_Clipboard.Data
{
public class DataSQLite : IData
{
public const string DATABASE = "data.sqlite";
public DataSQLite()
{
using (var db = new SQLiteDbContext(DATABASE))
{
// Ensure database is created with all changes to tables applied
db.Database.Migrate();
db.JumpLists.Add(new JumpList { Name = "Default" });
db.SaveChanges(); // Exception thrown here
}
}
}
}
The DbContext class
using JumpList_To_Clipboard.Data.Tables;
using Microsoft.EntityFrameworkCore;
namespace JumpList_To_Clipboard.Data
{
class SQLiteDbContext : DbContext
{
readonly string db_path;
public DbSet<JumpList> JumpLists { get; set; }
public DbSet<Group> Groups { get; set; }
public DbSet<Item> Items { get; set; }
public SQLiteDbContext(string database) : base()
{
db_path = database;
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlite(string.Format("Data Source={0}", db_path));
}
}
}
The JumpList class
using System.Collections.Generic;
namespace JumpList_To_Clipboard.Data.Tables
{
public class JumpList
{
public int JumpListId { get; set; }
public string Name { get; set; }
public List<Group> Groups { get; set; }
public List<Item> Items { get; set; }
}
}
The other two classes aren't worth repeating here, and don't give errors.
When I use the firefox sqlite extension to look at the data.sqlite file, none of my three tables are listed.
The command db.DataBase.Migrate says it
Applies any pending migrations for the context to the database.
What are pending migrations? I can't seem to find any documentation anywhere on these.
I'm combining examples from:
https://learn.microsoft.com/en-us/ef/core/get-started/netcore/new-db-sqlite
https://blogs.msdn.microsoft.com/dotnet/2016/09/29/implementing-seeding-custom-conventions-and-interceptors-in-ef-core-1-0/
Edit: If I replace db.Database.Migrate(); with db.Database.EnsureCreated(); it works. From the documentation, Migrate() is the same, but lets you create updates to the table structures, where EnsureCreated() does not. I'm confused.
So,
Microsoft has a serious issue making decent documentation, but I did find a site that has somewhat dated documentation for Learning Entity Framework Core, specifically migrations which is in the link.
At the top, it mentions,
If you have Visual Studio, you can use the Package Manager Console (PMC) to manage migrations.
Which led to the Package Manager Console page which states right at the top, that you need to have:
If you want to use the Package Manager Console to execute migrations command, you need to ensure that the latest version of Microsoft.EntityFrameworkCore.Tools is added to your project.json file.
The problem is, there is no project.json file anywhere in my project (or solution). After some searching, I found that via NuGet, to add Microsoft.EntityFrameworkCore.Tools
Then via Tools > NuGet Package Manager > Package Manager Console I was able to run the add-migration InitialDatabases command. The last part InitialDatabases is the name of the class it creates for you, and sticks in a folder called Migrations at the base of the project.
Now when:
context.Database.Migrate();
is run, all is well!
Try this (worked for me in a project a few months ago, i don't remember why):
public virtual DbSet<JumpList> JumpLists { get; set; }
public virtual DbSet<Group> Groups { get; set; }
public virtual DbSet<Item> Items { get; set; }
Also i had to use LONG instead of INT for classes ID because sqlite uses LONG as default for table ID, so after when you do a CRUD operation it fails because it can't compare/convert/cast LONG(64) to INT(32).

SQLite-Net Extensions Example on Xamarin Forms

I am intersted in using SQlite-Net Extensions (https://bitbucket.org/twincoders/sqlite-net-extensions) with Xamarin Forms. I am using Visual Studio 2013, SQlite.Net PCL 2.3.0 from NuGet, and a blank Hello World Xamarin Forms PLC project. As a first step I am trying to just get the example from the Sqlite.Net extensions site working. As per the suggested method on the Xamarin website I am using DependencyService to get the SQLIteConnection. However, my code will not even compile since it cannot find UpdateWithChildren nor GetWithChildren methods on the SQLiteConnection. It seems obvious that my SQLiteConnection object does not have all the same things as the example. Am I using the wrong library for SQLite.Net PCL? Both Xamarin and SQLite-Net Extensions suggested using the PCL version from NuGet, which is what I think I have...
I have this posted on the Xamarin Forums as well here:
http://forums.xamarin.com/discussion/20117/sqlite-net-extensions-and-sqliteconnection#latest
Here is my code (except for the ISQLite class).
Data Models:
using SQLiteNetExtensions.Attributes;
using SQLite.Net.Attributes;
namespace Sample.Models
{
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; }
}
}
And here is my DatabaseHelper. Right now I'm just running a test right in the constructor. The error I get is that the methods UpdateWithChildren and GetWithChildren cannot be found.
using Sample.Models;
using SQLite.Net;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace Sample.Orm
{
class DatabaseHelper
{
private SQLiteConnection db;
public DatabaseHelper()
{
db = DependencyService.Get<ISQLite>().GetConnection();
//Create the tables
db.CreateTable<Stock>();
db.CreateTable<Valuation>();
var euro = new Stock()
{
Symbol = "€"
};
db.Insert(euro); // Insert the object in the database
var valuation = new Valuation()
{
Price = 15,
Time = DateTime.Now,
};
db.Insert(valuation); // Insert the object in the database
// Objects created, let's stablish the relationship
euro.Valuations = new List<Valuation> { valuation };
db.UpdateWithChildren(euro); // Update the changes into the database
if (valuation.Stock == euro)
{
Debug.WriteLine("Inverse relationship already set, yay!");
}
// Get the object and the relationships
var storedValuation = db.GetWithChildren<Valuation>(valuation.Id);
if (euro.Symbol.Equals(storedValuation.Stock.Symbol))
{
Debug.WriteLine("Object and relationships loaded correctly!");
}
}
}
}
SQLite-Net Extensions is now available as NuGet packages for MvvmCross and standard PCL flavors of SQLite-Net. This should fix this kind of issues where the library was compiled with one SQLite-Net version but executed with another, that could cause the kind of issues that you are describing.
The links:
For SQLite-Net PCL: https://www.nuget.org/packages/SQLiteNetExtensions/
For MvvmCross SQLite Community plugin: https://www.nuget.org/packages/SQLiteNetExtensions-MvvmCross/
Jon Goldberger from Xamarin support pointed me in the right direction. For those finding this post in the future, the solution in short, is that unless you are using MvvmCross you need to build SQLite-Net Extensions from source, do not use the precompiled dll. Once you pull from their git server, you need to add the SQLiteNetExtensions-PCL.csproj, restore it's packages with Project->Restore Packages and then reference the SQLiteNetExtensions-PCL project from your base project.
Here is the fully qualify class (namespace and method).
Just added:
SQL Lite Extensions
SQLiteNetExtensions.Extensions.ReadOperations.GetAllWithChildren()
SQLiteNetExtensions.Extensions.WriteOperations.UpdateWithChildren()

(are you missing a using directive or an assembly reference?)

i am writing common business logic class in App_code folder for connecting to database using EFW.but showing the following error " Error 1 The type or namespace name 'job' could not be found"
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data;
namespace WebApplication6.App_Code
{
public class BlCommon
{
public List<job> GetJobs()
{
pubs2012Entities pubsobject = new pubs2012Entities();
var x = pubsobject.jobs.ToList<job>();
return x;
}
}
}
and class generated by EFW from jobs table is
namespace WebApplication6.App_Code
{
using System;
using System.Collections.Generic;
public partial class job
{
public short job_id { get; set; }
public string job_desc { get; set; }
public byte min_lvl { get; set; }
public byte max_lvl { get; set; }
}
}
Seem you dont have a reference to assembly wich contain mentioned class
Ok I got it:
Public List<job> GetJobs()
{
pubs2012Entities pubsobject = new pubs2012Entities();
var x = pubsobject.jobs.ToList<job>();
return x;
}
Click on Job, Move the mouse cursor over the blue dash that appear at the bottom of
job click Generate Class and then move your Job.cs code to your new job.cs class and
delete the old one.

Microsoft.VisualStudio.Shell.Interop.ToolWindowPane Class gives error when compiling in Visual Studio 2013 preview

I'm building a Visual Studio package for Visual Studio 2013..This same package works perfectly for Vs 2012 and previous.
This is the code of the class:
public class MyClassWindowPane : ToolWindowPane
{
public MyClassPanel MyClassPanelControl;
public List<IVsDataExplorerConnection> Connections { get; set; }
public string SelectedConnectionName { get; set; }
public MyClassWindowPane()
: base(null)
{
MyClassPanelControl = new MyClassPanel();
}
public void InitializeMyClassPanel()
{
MyClassPanelControl.LoadConnections(Connections, SelectedConnectionName);
}
override public IWin32Window Window
{
get { return (IWin32Window)MyClassPanelControl; }
}
}
The errors I'm getting are the following:
Cannot find the interop type that matches the embedded interop type 'Microsoft.VisualStudio.Shell.Interop.IVsWindowSearch'. Are you missing an assembly reference?
Cannot find the interop type that matches the embedded interop type 'Microsoft.VisualStudio.Shell.Interop.IVsUIElementPane'. Are you missing an assembly reference?
I'm including the following references
using Microsoft.VisualStudio.Shell;
using System.Windows.Forms;
using System.ComponentModel.Design;
using System.Runtime.InteropServices;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.Win32;
which should be more than enough to compile..
Looks like the culprit is on the ToolWindowPane class, since if I remove it everything compiles without any error.
Does anybody knows why is this issue occurring?
Thanks in advance for any lead
I have already tried the solution mentioned here Interop type cannot be embedded with no luck:
The problem is a result of one of your referenced dlls referencing another dll(for example as the return type from a method or property.) It is a flaw of the CLR. You can get around it by referencing the needed dll (in this case, Microsoft.VisualStudio.Shell.Interop.10). That solved it for me.
Read more here: http://blogs.msdn.com/b/vbteam/archive/2010/06/11/troubleshooting-errors-when-embedding-type-information-doug-rothaus.aspx
I had to do some changes so here is the code that finally worked:
using System.Windows.Forms;
using System.Runtime.InteropServices;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Data.Services;
using System.Collections.Generic;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio;
namespace My.VisualStudio.Package
{
public class MyClassWindowPane : ToolWindowPane, IVsWindowFrameNotify2
{
public MyClassPanel MyClassPanelControl;
public List<IVsDataExplorerConnection> Connections { get; set; }
public string SelectedConnectionName { get; set; }
public MyClassWindowPane()
: base(null)
{
MyClassPanelControl = new MyClassPanel();
}
public void InitializeMyClassPanel()
{
MyClassPanelControl.LoadConnections(Connections, SelectedConnectionName);
}
override public IWin32Window Window
{
get { return (IWin32Window)MyClassPanelControl; }
}
}

Reading values from DBML(having stored procedure)

I have a dbml that has stored procedures dragged off.I have EmployeeModel class that has get and set propertise .
I have an interface IEmployee and a Repository Employee Repository that has the implementation of the methods.Please refer the code.In Stored procedure GetRoles i just have SELECT * FROM ROLE .
In repository how to loop through the resultset.Can i change ISingleResult to IMultipleResult in dbml designer file?
EmployeeModel.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace MvcWebsite.Models
{
public class EmployeeModel
{
public int RoleId { get; set; }
public string RoleName { get; set; }
public string Description { get; set; }
public string TaskMark { get; set; }
public int RoleFlag { get; set; }
}
}
IEmployee:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MvcWebsite.Models;
namespace MvcWebsite.DAL
{
public interface IEmployees
{
IList<EmployeeModel> ListAll();
// void Save(EmployeeModel employ);
}
}
EmployeeRepository.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using MvcWebsite.Models;
using System.Data.Linq;
namespace MvcWebsite.DAL
{
public class EmployeeRepository:IEmployees
{
private DataDataContext _dataContext;
public EmployeeRepository()
{
_dataContext = new DataDataContext();
}
public IList<EmployeeModel> ListAll()
{
//IMultipleResults result =_dataContext.GetRoleDetails();
//var Emps = result.GetResult(EmployeeModel);
List<EmployeeModel> emp = _dataContext.GetRoleDetails();
// foreach (GetRoleDetailsResult role in Emps)
// {
// role.Description=Emps.
// }
return Emps.ToList();
}
}
}
You can loop through the resultset as below:
List<EmployeeModel> employeeModels = new List<EmployeeModel>();
foreach (EmployeeModel employeeModel in _dataContext.GetRoleDetails())
{
employeeModels.Add(employeeModel);
}
Or you can use System.Linq.Enumerable class ToList<> method as below:
List<Product> products = context.GetProducts().ToList<Product>();
IMultipleResults is used when stored procedure is returning more than one result sets. However when you drop such procedures on to the designer, it doesn't generate IMultipleResults. For this you can change the designer generated code to use IMultipleResults as below:
[global::System.Data.Linq.Mapping.FunctionAttribute(Name="dbo.GetCustomerAndProducts")]
[ResultType(typeof(Customer))]
[ResultType(typeof(Product))]
public IMultipleResults GetCustomerAndProducts()
{
IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())));
return ((IMultipleResults)(result.ReturnValue));
}
However, it would overwrite your modifications when you do any changes in the designer because it would regenerate the code. To avoid this you can use partial classes.
Or you can also use SqlMetal tool. It is a command-line tool that generates code and mapping for the LINQ to SQL component of the .NET Framework. This tool generates IMultipleResults. You can get the details for this tool here:
http://msdn.microsoft.com/en-us/library/bb386987.aspx
Edited:
Repository functionality will be same regardless of you work in ASP.Net Mvc or WinForms or any other presentation layer.
You can change your repository function to below:
public List<EmployeeModel> ListAll()
{
return _dataContext.GetRoleDetails().ToList<EmployeeModel>();
}
Or:
public List<EmployeeModel> ListAll()
{
List<EmployeeModel> employeeModels = new List<EmployeeModel>();
foreach (EmployeeModel employeeModel in _dataContext.GetRoleDetails())
{
employeeModels.Add(employeeModel);
}
return employeeModels;
}

Resources