check db file is exist or not? - sqlite

I want to create a shared template in which I want to check the SQLite database file is exists or not, and if the file does not exist then create a new DB file in xamarin.
//my function
public Task<CreateDatabase> DbConnection(string DbName, string DbPath)
{
string dbname = DbName.ToLowerInvariant();
string path = Path.Combine(DbPath, dbname);
var database = new CreateDatabase(path);
if (File.Exists(path) == false)
{
var database = new CreateDatabase(path);
}
return null;
}
properties
public class CreateDatabase
{
public string databasePaths { get; }
public CreateDatabase(string databasePath)
{
databasePaths = databasePath;
}
}

You could use Flags to check and create the database if the database doesn't exist.
public static class Constants
{
public const SQLite.SQLiteOpenFlags Flags =
// open the database in read/write mode
SQLite.SQLiteOpenFlags.ReadWrite |
// create the database if it doesn't exist
SQLite.SQLiteOpenFlags.Create |
// enable multi-threaded database access
SQLite.SQLiteOpenFlags.SharedCache;
}
And then set the Flags when you build the connection.
Database = new SQLiteAsyncConnection(Constants.DatabasePath, Constants.Flags);
You could download the sample code form the link below for reference.
https://learn.microsoft.com/en-us/samples/xamarin/xamarin-forms-samples/todo/

Related

Using Entity Framework, ASP.NET MVC Core, and PostgreSQL with Heroku

I am attempting to use a PostgreSQL database managed by Heroku in an ASP.NET MVC app running on .NET core 2.0. I would like to be able to use the Entity Framework to easily read and write to the database. I am extremely new to all of these things except for ASP.NET, which is likely obvious, and having previously used a local SQLite server for this same purpose, I have almost no understanding of how PostgreSQL works with Heroku and the Entity Framework.
I have installed the Npgsql extension to the Entity Framework. I am stuck at the Entity Framework's connection string for this particular setup and how to use it with Heroku. Heroku supplies a DATABASE_URL variable (documented here), which is necessary to use because the database connection credentials are subject to change and Heroku automatically updates the variable when they change.
//This method gets called by the runtime. Use this method to add services to
//the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
string connection = "???";
services.AddDbContext<MyDbContext>(options => options.UseNpgsql(connection));
}
What value do I use for connection such that it will connect to the database through Heroku's URL independently of the current credentials? Additionally, how can I ensure that a table will be created in the database matching MyDbContext's model?
My goal is simply to have a database accessible (read and write) from a deployed Heroku website. It would be nice if I could also access the database locally for development purposes, but my only requirement is that this work on the hosted website and that the database is managed by Heroku (I went with PostgreSQL, Kafka and Redis are also available through Heroku).
The solution here is to "parse" the content of the DATABASE_URLenvironment variable provided by Heroku and use it to build the connection string in the format that the Npgsql expects.
For a quick and dirty solution, you can just follow this solution: .net core - database url parser.
For my project I decided to go a little further and created a class for that, based in the other connection string builders (for MS SQL, Mongo and etc):
public enum SslMode
{
Require,
Disable,
Prefer
}
public class PostgreSqlConnectionStringBuilder : DbConnectionStringBuilder
{
private string _database;
private string _host;
private string _password;
private bool _pooling;
private int _port;
private string _username;
private bool _trustServerCertificate;
private SslMode _sslMode;
public PostgreSqlConnectionStringBuilder(string uriString)
{
ParseUri(uriString);
}
public string Database
{
get => _database;
set
{
base["database"] = value;
_database = value;
}
}
public string Host
{
get => _host;
set
{
base["host"] = value;
_host = value;
}
}
public string Password
{
get => _password;
set
{
base["password"] = value;
_password = value;
}
}
public bool Pooling
{
get => _pooling;
set
{
base["pooling"] = value;
_pooling = value;
}
}
public int Port
{
get => _port;
set
{
base["port"] = value;
_port = value;
}
}
public string Username
{
get => _username;
set
{
base["username"] = value;
_username = value;
}
}
public bool TrustServerCertificate
{
get => _trustServerCertificate;
set
{
base["trust server certificate"] = value;
_trustServerCertificate= value;
}
}
public SslMode SslMode
{
get => _sslMode;
set
{
base["ssl mode"] = value.ToString();
_sslMode = value;
}
}
public override object this[string keyword]
{
get
{
if (keyword == null) throw new ArgumentNullException(nameof(keyword));
return base[keyword.ToLower()];
}
set
{
if (keyword == null) throw new ArgumentNullException(nameof(keyword));
switch (keyword.ToLower())
{
case "host":
Host = (string) value;
break;
case "port":
Port = Convert.ToInt32(value);
break;
case "database":
Database = (string) value;
break;
case "username":
Username = (string) value;
break;
case "password":
Password = (string) value;
break;
case "pooling":
Pooling = Convert.ToBoolean(value);
break;
case "trust server certificate":
TrustServerCertificate = Convert.ToBoolean(value);
break;
case "sslmode":
SslMode = (SslMode) value;
break;
default:
throw new ArgumentException(string.Format("Invalid keyword '{0}'.", keyword));
}
}
}
public override bool ContainsKey(string keyword)
{
return base.ContainsKey(keyword.ToLower());
}
private void ParseUri(string uriString)
{
var isUri = Uri.TryCreate(uriString, UriKind.Absolute, out var uri);
if (!isUri) throw new FormatException(string.Format("'{0}' is not a valid URI.", uriString));
Host = uri.Host;
Port = uri.Port;
Database = uri.LocalPath.Substring(1);
Username = uri.UserInfo.Split(':')[0];
Password = uri.UserInfo.Split(':')[1];
}
}
And then, in my Startup.cs, in the Configuration method, I have:
var builder = new PostgreSqlConnectionStringBuilder(Configuration["DATABASE_URL"])
{
Pooling = true,
TrustServerCertificate = true,
SslMode = SslMode.Require
};
services.AddEntityFrameworkNpgsql()
.AddDbContext<TTRDbContext>(options => options.UseNpgsql(builder.ConnectionString));
If you are accessing your DB from outside Heroku network (e.g. your local environment), you need to add the SSL Mode and Trust Server Certificate.
Hope it helps

Log structured data to Azure Storage table by Serilog store all object in RenderedMessage, I want column for each field in class

I write below code to log/store logs with an objects to Azure Table Storage by using SeriLog, But I got the object stored in "RenderedMessage" column (in azure table) or "Data" column, While I need to store each field/property in the class to a separated column in the Table storage.
Please see below:
var _simpleTransation = new SimpleTransation(99, "some title9", "type99");
var logger = new LoggerConfiguration()
.WriteTo.AzureTableStorage(storage,LogEventLevel.Information,null, "LogStorage",false,null,null,null,false)
.Enrich.WithProperty("SimpleTransation", "#_simpleTransation", true)
.Enrich.FromLogContext()
.CreateLogger()
.ForContext<SimpleTransation>();
logger.Information<SimpleTransation>("{#SimpleTransation}", _simpleTransation);
So I need to add columns to azure storage table that represent my object fields and not serialize my whole object inside RenderedMessage log?
So I need to add columns to azure storage table that represent my object fields and not serialize my whole object inside RenderedMessage log?
You could use propertyColumns attribute to add a new column when you write to azure table storage.
Note:You need to call Enrich.FromLogContext() and the property would show up in the Azure Table Storage.
Here is an article about Enrichment. Log events can be enriched with properties in various ways.
You need to use LogContext.PushProperty to add what property and value you want to add.
You could refer to the following code to have a try:
static void Main(string[] args)
{
var storage = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("StorageConnectionString"));
string tableName = "table411";
var exampleuser = new User { Id = 1, Name = "joey", Age = 23 };
var _log = new LoggerConfiguration()
.Enrich.FromLogContext()
.WriteTo.AzureTableStorageWithProperties(storage, propertyColumns: new string[] { "UserId" });
LogContext.PushProperty("UserId", exampleuser.Id);
var logger = _log.CreateLogger();
logger.Information("{#User}",exampleuser);
}
class User
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}
Screen shot:

Multipart/form-data file upload in asp.net core web api

How to do Multipart-form-data file upload in asp.net core web api? Is it possible to POST both JSON and the image at the same time in a single POST?
Update- .net core 2.0 +
With .net core you can leverage the new IFormFile interface to upload both the image and properties in the same post. For example:
[HttpPost("content/upload-image")]
public async Task<IActionResult> UploadImage(MyFile upload)
The MyFile class can look like:
public class MyFile
{
public string userId { get; set; }
public IFormFile File { get; set; }
// Other properties
}
You can access the properties and the file as follows:
var file = upload.File // This is the IFormFile file
var param = upload.userId // param
To persist/save the file to disk you can do the following:
using (var stream = new FileStream(path, FileMode.Create))
{
await file.File.CopyToAsync(stream);
}
.NET Framework
Yes it is. Depending on the client Framework you're using, you can configure your Web API for Content Type-Multipart, then do something like:
[HttpPost]
[Route("content/upload-image")]
public async Task<HttpResponseMessage> Post()
{
if (!Request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
// enter code here
}
Define and setup the directory where your image will be saved.
var root = HttpContext.Current.Server.MapPath("~/Content/Images/");
if (!Directory.Exists(root))
{
Directory.CreateDirectory(root);
}
Setup the StreamProvider and attempt to get the model data, which is the JSON you mentioned.
var streamProvider = new MultipartFormDataStreamProvider(root);
var result =
await Request.Content.ReadAsMultipartAsync(streamProvider);
if (result.FormData["model"] == null)
{
throw new HttpResponseException(HttpStatusCode.BadRequest);
}
Now access the files in the request.
try
{
// Deserialize model data to your own DTO
var model = result.FormData["model"];
var formDto = JsonConvert
.DeserializeObject<MyDto>(model, new IsoDateTimeConverter());
var files = result.FileData.ToList();
if (files != null)
{
foreach (var file in files)
{
// Do anything with the file(s)
}
}
}

sqlite-pcl database initialization in android platform

I have a very strange case using sqlite-pcl in android platform ... I have one class for database which is inherited from SQLiteConnection, I use personal folder for my db, in constructor I have one check for existence, but often when I start application again , without deleting any files, it return false...
public class ScannifyDatabase : SQLiteConnection
{
public static string DBPath
{
get
{
string path = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
return System.IO.Path.Combine(path, "Scaniff.db3");
}
}
public ScannifyDatabase(string path)
: base(new SQLitePlatformAndroid(),path)
{
if (!TableExists())
{
this.CreateTable<DocumentType>();
InitData();
}
}
private bool TableExists()
{
// return this.TableExists();
const string cmdText = "SELECT name FROM sqlite_master WHERE type='table' AND name=?";
var cmd = this.CreateCommand(cmdText, typeof(DocumentType).Name);
var res = !string.IsNullOrEmpty(cmd.ExecuteScalar<string>());
return res;
}
}
what the problem is?
In Xamarin Studio, under Preferences --> Android, be sure that you have "Preserve data/cache between application deploys" checked. There is a similar setting in Visual Studio.

C# Windows forms - Data Conduit to connect to a windows form app

Hi guys I need some help with this dataconduit. Its written by my tutor and we used it on a web development project. I am trying to use it for a windows forms application to connect to the database but i get the following error:
An attempt to attach an auto-named database for file C:\Users.... failed. A database with the same name exists, or specified file cannot be opened, or it is located on UNC share.
The data conduit works indeed if i use it on a asp.net website but not on a windows forms
i did try to researched but no luck.
I am just testing it with two text box and a save button
thank you
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.SqlClient;
using System.Data.OleDb;
using System.Data;
///This class uses the ado.net sql classes to provide a connection to an sql server database.
///it is free for use by anybody so long as you give credit to the original author i.e me
///Matthew Dean mjdean#dmu.ac.uk De Montfort University 2011
//you will need to modify the name of the namespace to suit your own program.
namespace MyClassLibrary
{
public class clsDataConduit
{
//connection object used to connect to the database
SqlConnection connectionToDB = new SqlConnection();
//data adapter used to transfer data to and from the database
SqlDataAdapter dataChannel = new SqlDataAdapter();
//ado.net class for building the sql commands
SqlCommandBuilder commandBuilder = new SqlCommandBuilder();
//stores a list of all of the sql parameters
List<SqlParameter> SQLParams = new List<SqlParameter>();
//data table used to store the results of the stored procedure
DataTable queryResults = new DataTable();
//data row used to store the data for a new record
DataRow newRecord;
//string variable used to store the connection string
private string connectionString;
public clsDataConduit()
{
//this is the constructor for the class
//you will need to modify this to suit your own database name and folder structure
//
//variable to store the patth to the database
string DbPath;
//variable to store the partial path and file name of your database
//modify this line to suit your own needs
string DatabaseName = "\\MyDatabase\\NamesData.mdf";
//set the DbPath concatenating the name of your database
DbPath = GetParentPath() + DatabaseName;
//build up the connection string for the sql server database
connectionString = "Data Source=.\\SQLEXPRESS;AttachDbFilename=" + DbPath + ";Integrated Security=True;User Instance=True";
}
private string GetParentPath()
///this function returns the path to the parent folder of the solution
{
//get the folder for the project
string DbPath = System.AppDomain.CurrentDomain.BaseDirectory;
//variable to store the position of the \\ characters
int Posn;
//loop through the path twice
for (int Counter = 0; Counter != 2; Counter++)
{
//find the right most instance of \\
Posn = DbPath.LastIndexOf("\\");
//split the path at that point
DbPath = DbPath.Substring(0, Posn);
//do it one more time
}
//return the new path
return DbPath;
}
public void AddParameter(string ParamName, string ParamValue)
///public method allowing the addition of an sql parameter to the list of parameters
///it accepts two parameters the name of the parameter and its value
{
//create a new instance of the sql parameter object
SqlParameter AParam = new SqlParameter(ParamName, ParamValue);
//add the parameter to the list
SQLParams.Add(AParam);
}
public void Execute(string SProcName)
{
///public method used to execute the named stored procedure
///accepts one parameter which is the name of the stored procedure to use
//open the stored procedure
//initialise the connection to the database
connectionToDB = new SqlConnection(connectionString);
//open the database
connectionToDB.Open();
//initialise the command builder for this connection
SqlCommand dataCommand = new SqlCommand(SProcName, connectionToDB);
//add the parameters to the command builder
//loop through each parameter
for (int Counter = 0; Counter < SQLParams.Count; Counter += 1)
{
//add it to the command builder
dataCommand.Parameters.Add(SQLParams[Counter]);
}
//set the command type as stored procedure
dataCommand.CommandType = CommandType.StoredProcedure;
//initialise the data adapter
dataChannel = new SqlDataAdapter(SProcName, connectionToDB);
//set the select command property for the data adapter
dataChannel.SelectCommand = dataCommand;
//use the copmmand builder to generate the sql insert delete etc
commandBuilder = new SqlCommandBuilder(dataChannel);
//fill the data adapter
dataChannel.Fill(queryResults);
//get the structure of a single record
newRecord = queryResults.NewRow();
//close the connection
connectionToDB.Close();
}
public void WriteToDatabase()
//void method that updates changes to the data adapter thus changing the database
{
//update any changes
dataChannel.Update(queryResults);
}
public DataRow NewRecord
///this method provides access to the new record as a single data row
{
get
{
//return the blank data row
return newRecord;
}
}
public void RemoveRecord(int Index)
//void method that removes a record at a specified index in the query results
{
//remove the record
queryResults.Rows[Index].Delete();
}
public void AddToDataTable()
//void method that adds the new record to the table data
{
//add the new record to the table
queryResults.Rows.Add(newRecord);
//re initialise the new record
newRecord = queryResults.NewRow();
}
public int Count
//property that returns the count of records in the query results
{
get
{
//return the count of the query results
return queryResults.Rows.Count;
}
}
public DataTable QueryResults
//public property that provides access to the query results
{
get
{
//return the query results
return queryResults;
}
set
{
//set the query results
queryResults = value;
}
}
}
}
this is the code for my name class.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MyClassLibrary
{
public class clsName
{
private string firstName;
private string lastName;
public string FirstName
{
get
{
return firstName;
}
set
{
firstName = value;
}
}
public string LastName
{
get
{
return lastName;
}
set
{
lastName = value;
}
}
public void Save()
{
clsDataConduit Names = new clsDataConduit();
Names.Execute("sproc_tblNames_GetAll");
Names.NewRecord["FirstName"] = firstName;
Names.NewRecord["LastName"] = lastName;
Names.AddToDataTable();
Names.WriteToDatabase();
}
}
}
thank you guys but i finally managed to make it work. i am not sure if it is the right way to do it but what u have done is i have commented out the public clsDataConduit() {} method and before this method i have modified the connection string adding the full path of my database as follow: private string connectionString = (#"Data Source=.\SQLEXPRESS;AttachDbFilename=C:\Users...\NamesData.mdf;Integrated Security=True;Connect Timeout=30;User Instance=True");

Resources