String.Copy alternative for dotnet core - .net-core

I'm trying to get the following code to work in dotnet core running on ubuntu linux - but getting a "string does not contain a definition for copy" compile error on this line - where apparently String.Copy is not supported in dotnet-core:
Attendance = String.Copy(markers) };
What are the best ways of doing a shallow string copy in dotnet Core? Should I use string.CopyTo?
Thanks
//I want to add an initial marker to each record
//based on the number of dates specified
//I want the lowest overhead when creating a string for each record
string markers = string.Join("", dates.Select(p => 'U').ToArray());
return logs.Aggregate( new List<MonthlyAttendanceReportRow>(), (rows, log) => {
var match = rows.FirstOrDefault(p => p.EmployeeNo == log.EmployeeNo);
if (match == null) {
match = new MonthlyAttendanceReportRow() {
EmployeeNo = log.EmployeeNo,
Name = log.FirstName + " " + log.LastName,
Attendance = String.Copy(markers) };
rows.Add(match);
} else {
}
return rows;
});

To complete Rogerson's answer, you can have an extension method which will do the exact thing that you are looking for.
using System;
using System.IO;
using System.Linq;
using System.Collections.Generic;
namespace CSharp_Shell
{
public static class ext{
public static string Copy(this string val){
return new String(val.ToArray());
}
}
public static class Program
{
public static void Main()
{
string b = "bbb";
var a = b.Copy();
Console.WriteLine("Values are equal: {0}\n\nReferences are equal: {1}.", Object.Equals(a,b), Object.ReferenceEquals(a,b));
}
}
}

Try this:
string b = "bbb";
var a = new String(b.ToArray());
Console.WriteLine("Values are equal: {0}\n\nReferences are equal: {1}.", Object.Equals(a,b), Object.ReferenceEquals(a,b));
You can see it running on this fiddle.

Related

Where to create SQLite DB and how to create a Select statement in any page

new to xamarin forms with SQLite. I need some guidance on how to use SQLite in Xamarin forms. Below is the code.
1) Create Interface
using System;
using SQLite.Net;
namespace SQLiteSample
{
public interface ISQLite
{
SQLiteConnection GetConnection();
}
}
2) Implementing ISQLite interface
using System;
using Xamarin.Forms;
using SQLiteEx.Droid;
using System.IO;
[assembly: Dependency(typeof(SqliteService))]
namespace SQLiteEx.Droid
{
public class SqliteService : ISQLite
{
public SqliteService() { }
public SQLite.Net.SQLiteConnection GetConnection()
{
var sqliteFilename = "myDB.db3";
// Documents folder
string documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
var path = Path.Combine(documentsPath, sqliteFilename);
Console.WriteLine(path);
if (!File.Exists(path)) File.Create(path);
var plat = new SQLite.Net.Platform.XamarinAndroid.SQLitePlatformAndroid();
var conn = new SQLite.Net.SQLiteConnection(plat, path);
// Return the database connection
return conn;
}
}
}
3) Class for Database Operation :CRUD
using SQLite.Net;
using Xamarin.Forms;
namespace SQLiteEx
{
public class DataAccess
{
SQLiteConnection dbConn;
public DataAccess()
{
dbConn = DependencyService.Get<ISQLite>().GetConnection();
// create the table(s)
dbConn.CreateTable<Employee>();
}
public List<Employee> GetAllEmployees()
{
return dbConn.Query<Employee>("Select * From [Employee]");
}
public int SaveEmployee(Employee aEmployee)
{
return dbConn.Insert(aEmployee);
}
public int DeleteEmployee(Employee aEmployee)
{
return dbConn.Delete(aEmployee);
}
public int EditEmployee(Employee aEmployee)
{
return dbConn.Update(aEmployee);
}
}
}
I would like to know :
1) Where is the place to create a database that can be used through out the app. This means I can use it anywhere in any page without recreating it each time I need to use it.
2) Will table be recreated each time in above code?
3) How to I do a select statement in any page ie CustomerPage.xaml or SalesPage.xaml ?
In WinRT, I used below code. How to do it in Xamarin forms? Do I need to recreate SQLite DB? How to get the Path?
Using (var db = new SQLite.SQLiteConnection(App.DBPath){
var query = db.query<CashReceivable>("select * from CashRcvdTbl where Cust='" + Id + "'";
foreach( var item in query)
{
}
}
1) Here,
string documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
This line in your ISQlite implementation points to your myDB.db3 SQLite file.
You can see this file into /data/data/#APP_PACKAGE_NAME#/files directory.
if (!File.Exists(path)) File.Create(path);
This line checks whether database file exists in above path or not. If not, then it creates this file once. This time it will be an empty sqlite file without any tables in it.
So, it will not recreated each time.
But, I think there is no need for this File exist check because, when you create a connection to the SQLite file, it automatically creates file if not exists.
So, it can be as simple as follows:
public class SqliteService : ISQLite
{
string dpPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), “myDB.db3”);
public SQLiteConnection GetConnection()
{
return new SQLiteConnection(new SQLite.Net.Platform.XamarinAndroid.SQLitePlatformAndroid(), dpPath, false);
}
}
2) Each time you create instance of DataAccess class, it will recreate Employee table/definition based on Table exists or not, as it calls dbConn.CreateTable<Employee>();
I generally write this line at Application Startup code.
public App ()
{
InitializeComponent ();
//Create all tables here. This will create them once when app launches.
using (var conn = DependencyService.Get<ISQLite>().GetConnection())
{
conn.CreateTable<Employee>();
}
MainPage = new HomePage ();
}
This will simply creates a new table in the SQLite file if table not exists, otherwise it updates the table definition.
3) You can do a select statement as follows:
public List<Employee> GetAllEmployees()
{
using (var conn = DependencyService.Get<ISQLite>().GetConnection())
{
return conn.Table<Employee>().ToList();
//OR
return conn.Query<Employee>("Select * From Employee");
}
}
In any page you can call this GetAllEmployees method to retrieve List of Employee.

Database file locked error while reading chrome history c#

I am developing an application, which requires chrome browser history. I have written a C# code for fetching the history. However there are two issues in my code which I am unable to figure out.
There is this warning.
Warning 1 There was a mismatch between the processor architecture of the project being built "MSIL" and the processor architecture of the reference "System.Data.SQLite", "AMD64". This mismatch may cause runtime failures. Please consider changing the targeted processor architecture of your project through the Configuration Manager so as to align the processor architectures between your project and references, or take a dependency on references with a processor architecture that matches the targeted processor architecture of your project. ChromeData
There is this error
SQLite error (5): database is locked
I tried closing the browser, but still there is this error. However, when I created a copy of History file and renamed it, gave its path instead of History, the program was working and it could read the file and fetch the data.
I am unable to figure it out where the error is. So, please help. I am posting my 3 class files.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Data.SQLite;
using System.Data;
namespace ChromeData
{
class GoogleChrome
{
public List<URL> Urls = new List<URL>();
public IEnumerable<URL> GetHistory()
{
string DocumentsFolder = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
//Console.WriteLine(DocumentsFolder);
string[] tempstr = DocumentsFolder.Split('\\');
foreach(string s in tempstr)
{
Console.WriteLine(s);
}
string tempstr1 = "";
DocumentsFolder += "\\Google\\Chrome\\User Data\\Default";
if(tempstr[tempstr.Length-1] != "Local")
{
for(int i =0; i<tempstr.Length-1;i++)
{
tempstr1 += tempstr[i] + "\\";
}
DocumentsFolder = tempstr1 + "Local\\Google\\Chrome\\User Data\\Default";
}
Console.WriteLine(DocumentsFolder);
if(Directory.Exists(DocumentsFolder))
{
return ExtractUserHistory(DocumentsFolder);
}
return null;
}
public IEnumerable<URL> ExtractUserHistory(string folder)
{
DataTable HistoryData = ExtractFromTable("urls", folder);
foreach(DataRow row in HistoryData.Rows)
{
string url = row["url"].ToString();
string title = row["title"].ToString();
URL u = new URL(url.Replace('\'',' '), title.Replace('\'',' '), "Google Chrome");
Urls.Add(u);
}
return Urls;
}
DataTable ExtractFromTable(string table, string folder)
{
SQLiteConnection sql_con;
SQLiteDataAdapter DB;
SQLiteCommand sql_cmd;
string dbpath = folder + "\\History";
DataTable DT = new DataTable();
if(File.Exists(dbpath))
{
try
{
sql_con = new SQLiteConnection("Data Source=" + dbpath + ";Version=3;New=False;Compress=True;");
sql_con.Open();
sql_cmd = sql_con.CreateCommand();
string CommandText = "select * from " + table;
DB = new SQLiteDataAdapter(CommandText, sql_con);
DB.Fill(DT);
sql_con.Close();
}
catch(Exception e)
{
TextWriter errorWriter = Console.Error;
errorWriter.WriteLine(e.Message);
}
}
return DT;
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace ChromeData
{
class TestClass
{
public static List<URL> Urls = new List<URL>();
public static void Main()
{
string path = #"C:\Users\Public\Desktop\history.txt";
GoogleChrome g = new GoogleChrome();
Urls = (List<URL>)g.GetHistory();
using(StreamWriter sw = File.CreateText(path))
{
foreach(URL u in Urls)
{
sw.WriteLine(u.url);
}
}
Console.ReadLine();
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ChromeData
{
class URL
{
public string url;
public string title;
public string browser;
public URL(string url,string title,string browser)
{
this.browser = browser;
this.title = title;
this.url = url;
}
}
One solution is to copy the file to a temporary location and read it from there.
string source = #"C:\Users\{USERNAME}\AppData\Local\Google\Chrome\User Data\Default\History";
string target = #"C:\Temp\History";
if (File.Exists(target))
{
File.Delete(target);
}
File.Copy(source, target);
string cs = #"Data Source=" + target;
string sql = "Select * From urls";
using (SQLiteConnection c = new SQLiteConnection(cs))
{
c.Open();
using (SQLiteCommand cmd = new SQLiteCommand(sql, c))
{
using (SQLiteDataReader rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
Console.WriteLine(rdr[1].ToString());
}
}
}
}
I've found chrome.exe will continue running, and holding the lock, despite exiting the browser as normal.
taskkill.exe /IM chrome.exe /F
This will shut down Chrome, with an added bonus of having a 'restore tabs' button upon restart by the user. Restore tabs is available because you killed forcefully.

converting query to list (not working) asp.net mvc

I am trying to create a query whose results will be stored in a ViewModel. When I try to assign the query variable to the ViewModel's method, I get the following error: "cannot implicitly convert type 'System.Linq.Iqueryable' to 'System.Collections.Generic.List'. An explicit-conversion exists (are you missing a cast?)".
I tried changing my ViewModel's methods to be of type Iqueryable instead of List which worked but then I couldn't use a foreach loop in my view to loop through my model so I changed it back to List. I tried doing ToList() after my query but that didn't work either. Any suggestions/hints/tips are greatly appreciated. Below is my controller code and my ViewModel code.
ViewModel:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using KU_PLAN_DEV.Models;
namespace KU_PLAN_DEV.ViewModels
{
public class TrackViewModel
{
public List<string> TRACK_INFO { get; set; }
public List<string> GEN_ED_HEAD { get; set; }
}
}
Controller method:
public ActionResult DisplayTrackSheet(string trackButton)
{
var db = new KuPlanEntities();
var trackProgNum = (from info in db.TRACK_INFO
where info.degreeName == trackButton
select info.progNum).ToString();
var trackVerNum = (from info in db.TRACK_INFO
where info.degreeName == trackButton
select info.versionNum).ToString();
/*var queryTrack = (from tracks in db.GEN_ED_HEAD
where tracks.)*/
var trackData = (from trackInfo in db.TRACK_INFO
where trackInfo.progNum == trackProgNum
&& trackInfo.versionNum == trackVerNum
select trackInfo);
var trackDisplayMod = new TrackViewModel
{
TRACK_INFO = trackData
};
return View(trackDisplayMod);
}
var trackDisplayMod = new TrackViewModel
{
TRACK_INFO = trackData.ToList()
};
What error do you get when you make that change?

How use custom class in WebMatrix v2?

I do first steps in the ASP.NET and I've a issue with classes. I would like to create a new custom class to support sessions and collect information about the number of users on my website.
I've created a class in file MySession.cs, which has been put in the dir called "App_data" by WebMatrix.
When I try to use this class in .cshtml file, it throws me information it couldn't found that class.
I found in the Web, the class should be placed in App_Code, so I've done it. However, in this moment it shows me an error that classes like "Request" couldn't been found.
How to use custom class in WebMatrix?
My c# code from .cshtml file looks like:
#{
MySession session = new MySession(60);
session.start();
var db = Database.Open("studia");
var data = db.Query("SELECT COUNT(*) as total FROM sessions");
}
and class file looks like:
using System;
using System.Collections.Generic;
using System.Web;
using System.Security.Cryptography;
using System.Data;
using System.Data.SqlClient;
/// <summary>
/// Summary description for sesss
/// </summary>
public class MySession
{
private String _session_id;
private int _session_time;
public MySession(int session_time = 60)
{
_session_time = session_time;
using (MD5 md5Hash = MD5.Create())
{
_session_id = (Request.Cookies["session_id"] != null) ? Server.HtmlEncode(Request.Cookies["sesion_id"].Value) : GetMd5Hash(md5Hash, DateTime.Now);
}
cleanup();
}
public bool isLogged()
{
if (Request.Cookies["session_id"] != null)
{
return true;
}
return false;
}
public void start(string username)
{
DateTime now = DateTime.Now;
var db = Database.Open("studia");
if (isLogged())
{
db.Query("UPDATE sessions SET start_time = " + now + " WHERE session_id = " + _session_id);
}
else
{
db.Query("INSERT INTO sessions (id, start_time, username) VALUES ('" + _session_id + "', '" + now + "', '" + username + "'");
}
HttpCookie session_cookie = new HttpCookie("session_id");
session_cookie.Value = DateTime.Now;
session_cookie.Expires = DateTime.Now.AddSeconds(_session_time);
Response.Cookies.Add(aCookie);
}
public void cleanup()
{
var db = Database.Open("studia");
db.Query("DELETE FROM sessions WHERE start_time < " + (DateTime.Now - _session_time));
}
static string GetMd5Hash(MD5 md5Hash, string input)
{
// Convert the input string to a byte array and compute the hash.
byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(input));
// Create a new Stringbuilder to collect the bytes
// and create a string.
StringBuilder sBuilder = new StringBuilder();
// Loop through each byte of the hashed data
// and format each one as a hexadecimal string.
for (int i = 0; i < data.Length; i++)
{
sBuilder.Append(data[i].ToString("x2"));
}
// Return the hexadecimal string.
return sBuilder.ToString();
}
// Verify a hash against a string.
static bool VerifyMd5Hash(MD5 md5Hash, string input, string hash)
{
// Hash the input.
string hashOfInput = GetMd5Hash(md5Hash, input);
// Create a StringComparer an compare the hashes.
StringComparer comparer = StringComparer.OrdinalIgnoreCase;
if (0 == comparer.Compare(hashOfInput, hash))
{
return true;
}
else
{
return false;
}
}
}
If you want to refer to the Request object in a class (as opposed to from within a page file) you need to use HttpContext.Current e.g.
public bool isLogged()
{
return HttpContext.Current.Request.Cookies["session_id"] != null;
}

ASP NET MVC Error In Function

This is my code. I got this sample from the Internet and I tried to modify it.
private void FillGridData()
{
//IQueryable<SVC> query = _customerService.GetQueryable();
_dataContext = new dbServiceModelDataContext();
var query = from m in _dataContext.SVCs
select m;
query = AddQuerySearchCriteria(query, _grid.SearchForm);
int totalRows = query.Count();
_grid.Pager.Init(totalRows);
if (totalRows == 0)
{
_grid.Data = new List<SVC>();
return;
}
query = AddQuerySorting(query, _grid.Sorter);
query = AddQueryPaging(query, _grid.Pager);
List<SVC> customers = query.ToList(); //***ERROR IN HERE***//
_grid.Data = customers;
}
The error says "Cannot order by type 'System.Object'.", what is the matter?
Do you have solution for me?
This is The AddQuerySorting Method THE PROBLEM IS IN HERE
is there anything wrong about the code? :(
private IQueryable<SVC> AddQuerySorting(IQueryable<SVC> query, Sorter sorter)
{
if (String.IsNullOrEmpty(sorter.SortField))
return query;
//Used approach from http://www.singingeels.com/Articles/Self_Sorting_GridView_with_LINQ_Expression_Trees.aspx
//instead of a long switch statement
var param = Expression.Parameter(typeof(SVC), "customer");
var sortExpression = Expression.Lambda<Func<SVC, object>>
(Expression.Convert(Expression.Property(param, sorter.SortField), typeof(object)), param);
if (sorter.SortDirection == SortDirection.Asc)
query = query.OrderBy(sortExpression);
else
query = query.OrderByDescending(sortExpression);
return query;
}
here is AddQueryPaging Method
private IQueryable<SVC> AddQueryPaging(IQueryable<SVC> query, Pager pager)
{
if (pager.TotalPages == 0)
return query;
query = query.Skip((pager.CurrentPage - 1) * pager.PageSize)
.Take(pager.PageSize);
return query;
}
Sorter
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Web;
namespace MvcGridSample.ViewModels.Shared
{
public enum SortDirection
{
Asc = 1,
Desc = 2
}
public class Sorter
{
//Properties
public string SortField { get; set; }
public SortDirection SortDirection { get; set; }
public Sorter()
{
this.SortDirection = SortDirection.Asc;
}
public Sorter(string sortField, SortDirection sortDirection)
{
Verify.Argument.IsNotEmpty(sortField, "sortField");
Verify.Argument.IsNotEmpty(sortField, "sortDirection");
this.SortField = sortField;
this.SortDirection = sortDirection;
}
public void AddToQueryString(NameValueCollection queryString)
{
queryString["Sorter.SortField"] = this.SortField;
queryString["Sorter.SortDirection"] = this.SortDirection.ToString();
}
}
}
Look at the line:
var sortExpression = Expression.Lambda<Func<SVC, object>>
That should immediately leap out as the cause. The generated Expression must be suitable typed. This type of metaprogramming often involves either using the non-generic API, or using reflection to create the correct type on the fly. Fortunately, a suitable example is here. You should be able to use that approach re MakeGenericMethod (or simpler: just use the code "as is" from inside AddQuerySorting).

Resources