I have this code should be working but this is throwing an exception Must declare variable scalar
public async Task<Job> GetJobByUd(Guid jobId)
{
var sql = "select * from dbo.Jobs where JobId = #jobId;";
using (DbConnection db = new SqlConnection(_connectionString))
{
var job = await db.QuerySingleOrDefaultAsync<Job>(sql, new {jobId});
return job;
}
}
Try like this, it should work.
public async Task<Job> GetJobByUd(Guid jobId)
{
var sql = "select * from dbo.Jobs where JobId = #jobId;";
using (DbConnection db = new SqlConnection(_connectionString))
{
var job = await db.QueryAsync<Job>(sql, new {jobId = jobId}).FirstOrDefault();
return job;
}
}
Related
"The non-nullable variable '_db' must be initialized. Try adding an initializer expression"
Could anyone help me with this non-nullable error?
I am using flutter to make an android app and while using the 'sqflite' and making a database, this error pops up I don't know how to really fix this
Here is my Code below,
I am using the last version of Flutter & Dart,
import 'dart:io';
import 'package:newtodoapp/taskmodel.dart';
import 'package:path_provider/path_provider.dart';
import 'package:sqflite/sqflite.dart';
class DatabaseHelper {
static final DatabaseHelper instance = DatabaseHelper._instance();
static Database _db;
DatabaseHelper._instance();
String tasksTable = 'task_table';
String colId = 'id';
String colTitle = 'title';
String colDate = 'date';
String colPriority = 'priority';
String colStatus = 'status';
// Task Tables
// Id | Title | Date | Priority | Status
// 0 '' '' '' 0
// 2 '' '' '' 0
// 3 '' '' '' 0
Future<Database> get db async {
if (_db == null) {
_db = await _initDb();
}
return _db;
}
Future<Database> _initDb() async {
Directory dir = await getApplicationDocumentsDirectory();
String path = dir.path + '/todo_list.db';
final todoListDb =
await openDatabase(path, version: 1, onCreate: _createDb);
return todoListDb;
}
void _createDb(Database db, int version) async {
await db.execute(
'CREATE TABLE $tasksTable($colId INTEGER PRIMARY KEY AUTOINCREMENT,'
' $colTitle TEXT, $colDate TEXT, $colPriority TEXT, $colStatus INTEGER)',
);
}
Future<List<Map<String, dynamic>>> getTaskMapList() async {
Database db = await this.db;
final List<Map<String, dynamic>> result = await db.query(tasksTable);
return result;
}
Future<List<Task>> getTaskList() async {
final List<Map<String, dynamic>> taskMapList = await getTaskMapList();
final List<Task> taskList = [];
taskMapList.forEach((taskMap) {
taskList.add(Task.fromMap(taskMap));
});
taskList.sort((taskA, taskB) => taskA.date.compareTo(taskB.date));
return taskList;
}
Future<int> insertTask(Task task) async {
Database db = await this.db;
final int result = await db.insert(tasksTable, task.toMap());
return result;
}
Future<int> updateTask(Task task) async {
Database db = await this.db;
final int result = await db.update(
tasksTable,
task.toMap(),
where: '$colId = ?',
whereArgs: [task.id],
);
return result;
}
Future<int> deleteTask(int id) async {
Database db = await this.db;
final int result = await db.delete(
tasksTable,
where: '$colId = ?',
whereArgs: [id],
);
return result;
}
}
declare your variable like this.
static Database? _db;
I was making an app and it keeps showing an error the method was called on null. When I looked up for answers it was specified that this occurs when method is not declared but in my case method has been already declared.
Due to this error I am not able to save data in my app.
initialiseDatabase is the function it states as called on null.
Here is the code-
static DatabaseHelper _databaseHelper; // singleton
static Database _database;
String noteTable = 'note_Table';
String colId = 'id';
String colTitle = 'title';
String colDescription = 'description';
String colPriority = 'priority';
String colDate = 'date';
DatabaseHelper._createInstance();// named constructor to create dbms helper
factory DatabaseHelper(){
if(DatabaseHelper == null) {
_databaseHelper = DatabaseHelper._createInstance();
}
return _databaseHelper;
}
Future<Database> get database async{
if(_database == null){
_database = await initializeDatabase();
}
return _database;
}
Future<Database> initializeDatabase() async {
Directory directory = await getApplicationDocumentsDirectory();
String path = directory.path + 'notes.db';
var notesDatabase = await openDatabase(path, version: 1, onCreate: _createDb);
return notesDatabase;
}
void _createDb(Database db, int newVersion) async{
await db.execute('CREATE TABLE $noteTable($colId INTEGER PRIMARY KEY AUTOINCREMENT, $colTitle TEXT.'
'$colDescription TEXT, $colPriority INTEGER, $colDate TEXT');
}
// Fetch Operation: Get all note objects from database
Future<List<Map<String, dynamic>>> getNoteMapList() async {
Database db = await this.database;
// var result = await db.rawQuery('SELECT * FROM $noteTable order by $colPriority ASC');
var result = await db.query(noteTable, orderBy: '$colPriority ASC');
return result;
}
// Insert Operation: Insert a Note object to database
Future<int> insertNote(Note note) async {
Database db = await this.database;
var result = await db.insert(noteTable, note.toMap());
return result;
}
// Update Operation: Update a Note object and save it to database
Future<int> updateNote(Note note) async {
var db = await this.database;
var result = await db.update(noteTable, note.toMap(), where: '$colId = ?', whereArgs: [note.id]);
return result;
}
// Delete Operation: Delete a Note object from database
Future<int> deleteNote(int id) async {
var db = await this.database;
int result = await db.rawDelete('DELETE FROM $noteTable WHERE $colId = $id');
return result;
}
// Get number of Note objects in database
Future<int> getCount() async {
Database db = await this.database;
List<Map<String, dynamic>> x = await db.rawQuery('SELECT COUNT (*) from $noteTable');
int result = Sqflite.firstIntValue(x);
return result;
}
// Get the 'Map List' [ List<Map> ] and convert it to 'Note List' [ List<Note> ]
Future<List<Note>> getNoteList() async {
var noteMapList = await getNoteMapList(); // Get 'Map List' from database
int count = noteMapList.length; // Count the number of map entries in db table
List<Note> noteList = List<Note>();
// For loop to create a 'Note List' from a 'Map List'
for (int i = 0; i < count; i++) {
noteList.add(Note.fromMapObject(noteMapList[i]));
}
return noteList;
}
}
While this is the function which it states as not declared
Future<Database> get database async{
if(_database == null){
_database = await initializeDatabase();
}
return _database;
}
Future<Database> initializeDatabase() async {
Directory directory = await getApplicationDocumentsDirectory();
String path = directory.path + 'notes.db';
var notesDatabase = await openDatabase(path, version: 1, onCreate: _createDb);
return notesDatabase;
}
So Initially I created a table named "TABLE" in the database. I wanted to add another table. So I added another query to create a table. However I get an error saying "TABLE1 does not exist" when I run the app.
I do feel like there is a flaw in my code. I think the _onCreate() method will only be called the first time I run the app. So any code I add on _onCreate() method afterwards will not run. Any help will be appreciated.
class DBHelper {
static Database _db;
static const String DB_NAME = 'employeeDB';
static const String ID = 'id';
static const String NAME = 'name';
static const String TABLE = 'Employee';
static const String ID1 = 'id1';
static const String NAME1 = 'name1';
static const String TABLE1 = 'Employee1';
Future<Database> get db async {
if (_db != null) {
return _db;
}
_db = await initDb();
return _db;
}
initDb() async {
io.Directory documentsDirectory = await getApplicationDocumentsDirectory();
String path = join(documentsDirectory.path, DB_NAME);
var db = await openDatabase(path, version: 1, onCreate: _onCreate);
return db;
}
_onCreate(Database db, int version) async {
await db.execute("CREATE TABLE $TABLE ($ID INTEGER PRIMARY KEY,$NAME TEXT)");
await db.execute("CREATE TABLE $TABLE1 ($ID1 INTEGER PRIMARY KEY,$NAME1 TEXT)");
}
Future<Employee> save(Employee employee) async {
var dbClient = await db;
employee.id = await dbClient.insert(TABLE, employee.toMap());
return employee;
}
Future<Employee1> saveEmp1(Employee1 employee) async {
var dbClient = await db;
employee.id = await dbClient.insert(TABLE1, employee.toMap());
return employee;
}
Future<List<Employee>> getEmployees() async {
var dbClient = await db;
List<Map> maps = await dbClient.query(TABLE, columns: [ID, NAME]);
List<Employee> employees = [];
if (maps.length > 0) {
for (int i = 0; i < maps.length; i++) {
employees.add(Employee.fromMap(maps[i]));
}
}
return employees;
}
Future<List<Employee1>> getEmployees1() async {
var dbClient = await db;
List<Map> maps = await dbClient.query(TABLE1, columns: [ID1,
NAME1]);
List<Employee1> employees = [];
if (maps.length > 0) {
for (int i = 0; i < maps.length; i++) {
employees.add(Employee.fromMap(maps[i]));
}
}
return employees;
}
}
The first time run this app and initDb() in emulator, the db file employeeDB has created.
and it will not be created again
For only test app execution,
you can change
String DB_NAME = 'employeeDB'
to another name
String DB_NAME = 'employeeDB1'
or you can uninstall this app from Emulator first then run it again.
source code snippet of https://github.com/tekartik/sqflite/blob/master/sqflite/lib/sqlite_api.dart
/// Called when the database is created.
OnDatabaseCreateFn onCreate;
For schema migration, you can use OnUpgrade, detail reference https://efthymis.com/migrating-a-mobile-database-in-flutter-sqlite/
code snippet
await openDatabase(path,
version: 1,
onCreate: (Database db, int version) async {
await db.execute(initialSchema));
},
onUpgrade: (Database db, int oldVersion, int newVersion) async {
await db.execute(migrationScript));
});
You have to create migrations and run them against your existing database using the onUpgrade handler. Basically you need to check the existing database version and upgrade if the version is smaller than the migration number.
You can check out the detail steps/code tutorial here.
I needed to create more than just multiple tables; but multiple database. I have since developed a dart package; sqlite_at_runtime that stretches to as far as creating all these entities at run time.
Below is an example code that creates three tables with similar attributes.
await Sqlartime.tableCreate(['sample1','sample2','sample3'],['name TEXT','age INTEGER','temp REAL']);
using (var connection = new SqlConnection(FiddleHelper.GetConnectionStringSqlServerW3Schools()))
{
var sql = "Select * FROM CUSTOMERS WHERE CustomerID in #abc";
var affectedRows = connection.Execute(sql, new { abc = 53 });
connection.BulkDelete(connection.Query<Customer>(sql).ToList());
}
The code above cannot work. Instead of directly passing the value inside the query "connection.BulkDelete(connection.Query("Select * FROM CUSTOMERS WHERE CustomerID in (53) ").ToList());", is there any method to pass the flexible value to BulkDelete? Thanks
You are not using the affectedRows:
using (var connection = new SqlConnection(FiddleHelper.GetConnectionStringSqlServerW3Schools()))
{
var sql = "Select * FROM CUSTOMERS WHERE CustomerID in #abc";
var affectedRows = connection.Execute<Customer>(sql, new { abc = 53 });
connection.BulkDelete(affectedRows.ToList());
}
I use c# and ef4.
I have a Model with an Entity with two proprieties int Id and string Title.
I need to write an ESQL query that is able to return bool TRUE if Id and Title are present in the DataSource. Please note Id is a PrimaryKey in my data storage.
Any idea how to do it?
You can do it by each code-snippets below:
1)
using (YourEntityContext context = new YourEntityContext ()) {
var queryString =
#"SELECT VALUE TOP(1) Model FROM YourEntityContext.Models
As Model WHERE Model.Id = #id AND Model.Title = #title";
ObjectQuery<Model> entityQuery = new ObjectQuery<Model>(queryString, context);
entityQuery.Parameters.Add(new ObjectParameter("id", id));
entityQuery.Parameters.Add(new ObjectParameter("title", title));
var result = entityQuery.Any();
}
2)
using (YourEntityContext context = new YourEntityContext ()) {
ObjectQuery<Model> entityQuery =
context.Models
.Where("it.Id = #id AND it.Title = #title"
, new ObjectParameter("id", id)
, new ObjectParameter("title", title)
);
var result = entityQuery.Any();
}
3)
var context = new YourEntityContext();
using (EntityConnection cn = context.Connection as EntityConnection) {
if (cn.State == System.Data.ConnectionState.Closed)
cn.Open();
using (EntityCommand cmd = new EntityCommand()) {
cmd.Connection = cn;
cmd.CommandText = #"EXISTS(
SELECT M FROM YourEntityContext.Models as M
WHERE M.Id == #id AND Model.Title = #title
)";
cmd.Parameters.AddWithValue("id", _yourId);
cmd.Parameters.AddWithValue("title", _yourTitle);
var r = (bool)cmd.ExecuteScalar();
}
}
4)
using (YourEntityContext context = new YourEntityContext ()) {
var queryString =
#"EXISTS(
SELECT M FROM YourEntityContext.Models as M
WHERE M.Id == #id AND Model.Title = #title
)";
ObjectQuery<bool> entityQuery = new ObjectQuery<bool>(queryString, context);
entityQuery.Parameters.Add(new ObjectParameter("id", id));
entityQuery.Parameters.Add(new ObjectParameter("title", title));
var result = entityQuery.Execute(MergeOption.AppendOnly).FirstOrDefault();
}
4 is the best way I suggest you. Good lock
What javad said is true, but another way is:
bool result = entities.Any(x=>x.Id == id && x.Title == title) ;
In fact because Id is primary key, DB prevent from occurrence of this more than one time .