Simple Linq to SQLIte application hangs on SubmitChanges() - linq

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SQLite;
using System.Data.Linq.Mapping;
using DbLinq.Data.Linq;
namespace LinqToSQLite
{
class Program
{
static void Main(string[] args)
{
string connectionString = "DbLinqProvider=Sqlite;Data Source=db2.sqlite";
DataContext db = new DataContext(connectionString);
db.ExecuteCommand(Person.CreateCommand);
Table<Person> table = db.GetTable<Person>();
table.InsertOnSubmit(new Person { Name = "Alfred" });
table.InsertOnSubmit(new Person { Name = "Brian" });
table.InsertOnSubmit(new Person { Name = "Charles" });
db.SubmitChanges();
var query = from p in table select p;
foreach (var p in query)
{
Console.WriteLine(p.ID + ". " + p.Name);
}
Console.WriteLine("Done");
Console.ReadLine();
}
}
[Table(Name = "Persons")]
class Person
{
[Column(IsPrimaryKey = true, IsDbGenerated = true)]
public int ID { get; set; }
[Column]
public string Name { get; set; }
public static string CreateCommand = "CREATE TABLE IF NOT EXISTS Persons ( Id INTEGER PRIMARY KEY, Name TEXT )";
}
}
I created simply application using dblinq to provide Linq to SQLite but it hangs on db.SubmitChanges(). What's the reason? I just wanted to create simply dblinq application without using DbMetal.exe... There is no error, no exception I'm clueless.

Problem was with DataContext and connectonString, to fix it I had to change...
string connectionString = "DbLinqProvider=Sqlite;Data Source=db2.sqlite;";
SQLiteConnection connection = new SQLiteConnection(connectionString);
DataContext db = new DataContext(connection);
... or add to DbLinqConnectionType to connectionString...
string connectionString = "DbLinqProvider=Sqlite;Data Source=db2.sqlite;";
connectionString += "DbLinqConnectionType=System.Data.SQLite.SQLiteConnection, System.Data.SQLite, Version=1.0.66.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139";
DataContext db = new DataContext(connectionString);

Related

How to retrieve the serialized field name of an Elasticsearch Nest.Field

I want to get the field name of a field which is created with Infer.Field<MyDocument>(doc => doc.StringField1).
Example code:
using System;
using Nest;
using Xunit;
namespace Elasticsearch.Tests
{
public class MyDocument
{
public string StringField1 { get; set; }
}
public class SerializeField
{
[Fact]
public void TestFieldName()
{
var connectionSettings = new ConnectionSettings(new Uri("http://myesdomain.com:9200"));
var client = new ElasticClient(connectionSettings);
var stringField = Infer.Field<MyDocument>(doc => doc.StringField1);
// TODO: Code to get then name of stringField when serialized
}
}
}
Can I leaverage the client in order to serialize the name of the stringField as it would do in any request?
Fortunately I found the answer myself:
Short:
client.SourceSerializer.Serialize(stringField, ms);
Complete:
using System;
using System.IO;
using System.Text;
using Nest;
using Xunit;
namespace Elasticsearch.Tests
{
public class MyDocument
{
public string StringField1 { get; set; }
}
public class SerializeField
{
[Fact]
public void TestFieldName()
{
var connectionSettings = new ConnectionSettings(new Uri("http://myesdomain.com:9200"));
var client = new ElasticClient(connectionSettings);
var stringField = Infer.Field<MyDocument>(doc => doc.StringField1);
string fieldName;
using (var ms = new MemoryStream())
{
client.SourceSerializer.Serialize(stringField, ms);
ms.Position = 0;
using (var reader = new StreamReader(ms, Encoding.UTF8))
{
fieldName = reader.ReadToEnd();
}
}
Assert.Equal("\"stringField1\"", fieldName);
}
}
}
There is a better solution that uses a Nest.FieldResolver.
using System;
using Nest;
using Xunit;
namespace Elasticsearch.Tests
{
public class MyDocument
{
public string StringField1 { get; set; }
}
public class TestClass
{
[Fact]
public void TestFieldName()
{
var connectionSettings = new ConnectionSettings(new Uri("http://myesdomain.com:9200"));
var fieldResolver = new FieldResolver(connectionSettings);
var stringField = Infer.Field<MyDocument>(doc => doc.StringField1);
var fieldName = fieldResolver.Resolve(stringField);
Assert.Equal("stringField1", fieldName);
}
}
}

Convert Expression<Func<T, bool>> to another Predicate Expression Expression<Func<U, bool>>

I want to convert One predicate Expression(Expression<Func<Item, bool>>) to another Predicate Expression (Expression<Func<ItemEntity, bool>>) but after converting I am not able to query through LINQ.
I Already try this and this approach but nothing work properly
can anyone tells me how to do it properly, My approach for this problems.
using System;
using System.Linq;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading.Tasks;
using System.Reflection;
public class ItemEntity {
public int ItemId {set;get;}
public int ItemParentId {set;get;}
public int ItemName {set;get;}
}
public class Item {
public int Id{ set;get;}
public int ParentId{set;get;}
public int Name {set;get;}
}
public class Program
{
public static Item Convert(ItemEntity itemChild)
{
return new Item()
{
Id = itemChild.ItemId,
ParentId = itemChild.ItemParentId,
Name = itemChild.ItemName
};
}
public async Task<IList<ItemEntity>> SelectAsync(Expression<Func<ItemEntity, bool>> predicate)
{
// using Microsoft.EntityFrameworkCore;
// private readonly DbContext _context; // Injected globally by using Service.AddScoped<ItemContext>();
// return await _context.Set<ItemEntity>().AsNoTracking().Where(predicate).ToListAsync();
return await Task.Run(() => new List<ItemEntity>()); // actually return the result with matching predicate
}
public async Task<List<Item>> GetItems(Expression<Func<Item, bool>> expression)
{
MethodInfo convertMethod = ((Func<ItemEntity, Item>)Convert).Method;
var p = Expression.Parameter(typeof(ItemEntity));
var converted = Expression.Lambda<Func<ItemEntity, bool>>(
Expression.Invoke(expression, Expression.Convert(p, typeof(Item), convertMethod)), p);
IList<ItemEntity> res = await SelectAsync(converted);
var t = res.Select(x => Convert(x)).ToList();
return t;
}
public static void Main()
{
Program pr = new Program();
Func<Expression<Func<Item, bool>>, Task<List<Item>>> getItem = pr.GetItems;
var res = getItem.Invoke(x => x.Id.Equals(1));
Console.WriteLine("Hello World");
}
}
but I am getting error
The LINQ expression 'DbSet()\r\n .Where(i => ((Item)i).Id.Equals(__Id_0))' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'. See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.
I don't able to understand it properly, as per my understanding I am using ToList() for client evaluation, but and also provide method to convert ItemEntity to Item.
I any other way to create fresh Expression Tree based on ItemEntity and then query on DBSet?
Any Help is appreciated
version used:
dot-net 5.0
Microsoft.EntityFrameworkCore 5.0.6
EntityFramework 6.4.4
Database SQL Server
Try the following approach. Main idea to use filter exactly on the projected DTO before materialization.
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading.Tasks;
public class ItemEntity
{
public int ItemId { set; get; }
public int ItemParentId { set; get; }
public int ItemName { set; get; }
}
public class Item
{
public int Id { set; get; }
public int ParentId { set; get; }
public int Name { set; get; }
}
public class Program
{
public static Expression<Func<ItemEntity, Item>> ToItem()
{
return itemChild => new Item
{
Id = itemChild.ItemId,
ParentId = itemChild.ItemParentId,
Name = itemChild.ItemName
};
}
public Task<IList<Item>> SelectAsync(Expression<Func<Item, bool>> predicate)
{
return _context.Set<ItemEntity>()
.AsNoTracking()
.Select(ToItem())
.Where(predicate)
.ToListAsync();
//return Task.Run(() => new List<ItemEntity>().AsQueryable().Select(ToItem()).Where(predicate).ToList());
}
public async Task<IList<Item>> GetItems(Expression<Func<Item, bool>> expression)
{
var res = await SelectAsync(expression);
return res;
}
public static void Main()
{
var pr = new Program();
var res = pr.GetItems(x => x.Id == 1);
Console.WriteLine("Hello World");
}
}

Execute or compile runtime c# code on textbox after changes event - "PlatformNotSupportedException"

I am wondering to provide an option in my application to users to be able to customize buttons in ASP.NET CORE with Blazor.
I mean, C# code can be stored in database, and compiled/executed in runtime.
How can I "provide" an object from razor to be manipulated in this "code stored in the database" and after that, make those changes in runtime, after code been executed?
Please share your ideas.
I already tried some things, like this:
using Blazored.Toast.Services;
using Microsoft.AspNetCore.Components;
using Microsoft.CSharp;using Newtonsoft.Json;
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
namespace Projeto.Web.Pages.Components {
public class McwEditModel : CustomComponentBase
{
[Inject]
public IToastService ToastService { get; set; }
#region Parameters
[Parameter]
public string nome { get; set; }
#endregion
public void OnTextChanged(string newValue)
{
string source =
#"public class SomeClass {
public int OnTextChanged (string newValue) {
if (!string.IsNullOrEmpty(newValue)) {
ToastService.ShowWarning(newValue);
}
}
} ";
var compParms = new CompilerParameters
{
GenerateExecutable = false,
GenerateInMemory = true
};
var csProvider = new CSharpCodeProvider();
CompilerResults compilerResults =
csProvider.CompileAssemblyFromSource(compParms, source);
object typeInstance =
compilerResults.CompiledAssembly.CreateInstance("SomeClass");
MethodInfo mi = typeInstance.GetType().GetMethod("OnTextChanged");
int methodOutput =
(int)mi.Invoke(typeInstance, new object[] { newValue });
InvokeAsync(StateHasChanged);
}
}}
The problem is that does not work, particularly I am getting the error "System.PlatformNotSupportedException: 'Operation is not supported on this platform.'" on line
" CompilerResults compilerResults = csProvider.CompileAssemblyFromSource(compParms, source); "
I am using Blazor .NET Core.
Is there any chance or way to achieve what I want?
I solved it using using Microsoft.CodeAnalysis package.
I needed to create a
public class Globals
{
[Inject]
public IToastService ToastService { get; set; }
public string newValue { get; set; }
public dynamic objeto { get; set; }
}
and inside my method I did:
public void OnTextChanged(string newValue){
Aql aql = new Aql { EaqcCodigo = "1", EaqcDescricao = "AQL" };
var globals = new Globals { ToastService = ToastService, newValue = newValue, objeto= aql };
CSharpScript.RunAsync("ToastService.ShowWarning(newValue + \"- desc:\" + objeto.EaqcDescricao + \"- cod:\" + objeto.EaqcCodigo);", ScriptOptions.Default.WithReferences("Microsoft.CSharp"), globals).Wait();
}
with this, now I can pass a dynamic object and also make any codes in a string field on database and retrieve this wherever I want, to customize a lot of things, ie: change of fields (in a custom generic and dynamic component)

Insertion operation in SqlCe in windows phone

I am trying to insert some data into mydatabase but getting error like "Can't perform Create, Update, or Delete operations on 'Table(Dic)' because it has no primary key."
My database name is "condrokotha_new.sdf" and it has a table named "dic" which have 2 columns named "english" and "bangla". I made this database in another C# project in vs 2010. Then i used this database into my windowsphone project. I can show data from database but when i try to insert data i am getting error.
Here is my code:
public partial class MainPage : PhoneApplicationPage
{
condrokotha_newContext db = null;
// Constructor
public MainPage()
{
InitializeComponent();
db = new condrokotha_newContext(condrokotha_newContext.ConnectionString);
db.CreateIfNotExists();
db.LogDebug = true;
}
private void fav_Click(object sender, RoutedEventArgs e)
{
add_new_words("cintakhela","ami");
}
private void add_new_words(string e_word,string b_word)
{
using (condrokotha_newContext context = new condrokotha_newContext(condrokotha_newContext.ConnectionString))
{
Dic d = new Dic();
d.English = e_word;
d.Bangla = b_word;
context.Dics.InsertOnSubmit(d);
context.SubmitChanges();
}
}
}
My data context code like these :
public static string ConnectionString = "Data Source=isostore:/condrokotha_new.sdf";
public static string ConnectionStringReadOnly = "Data Source=appdata:/condrokotha_new.sdf;File Mode=Read Only;";
public static string FileName = "condrokotha_new.sdf";
public condrokotha_newContext(string connectionString) : base(connectionString)
{
OnCreated();
}
#region Extensibility Method Definitions
partial void OnCreated();
#endregion
public System.Data.Linq.Table<Dic> Dics
{
get
{
return this.GetTable<Dic>();
}
}
}
[global::System.Data.Linq.Mapping.TableAttribute(Name="dic")]
public partial class Dic
{
private string _English;
private string _Bangla;
public Dic()
{
}
[global::System.Data.Linq.Mapping.ColumnAttribute(Name="english", Storage="_English", DbType="NVarChar(1000)")]
public string English
{
get
{
return this._English;
}
set
{
if ((this._English != value))
{
this._English = value;
}
}
}
[global::System.Data.Linq.Mapping.ColumnAttribute(Name="bangla", Storage="_Bangla", DbType="NText", UpdateCheck=UpdateCheck.Never)]
public string Bangla
{
get
{
return this._Bangla;
}
set
{
if ((this._Bangla != value))
{
this._Bangla = value;
}
}
}
}
`
How can i insert my data into my database??
Is there anyone who can help in this??
For example you have this
SampleDataContextDataContext db = new SampleDataContextDataContext();
Employee emp = new Employee() {
FirstName = "Experts",
Lastname = "Comment",
Address = "rs.emenu#gmail.com"
}
db.Employees.InsertOnSubmit(emp);
db.SubmitChanges();
The above code will give you same error when u try to insert a new row. The reason is that LINQ does not provide the facility to insert data into a table without a primary key. At this point you have two options.
1.Create a store procedure and call it from LINQ.
SampleDataContextDataContext db = new SampleDataContextDataContext();
db.InsertEmployeeData("Experts","Comment", "rs.emenu#gmail.com");
Here InsertEmployeeData is a a stored procedure, and called it from the code.
2.Create an insert statement and execute using LINQ.
SampleDataContextDataContext db = new SampleDataContextDataContext();
string insertStatement = "Insert into Employee values('Experts', 'Comment','rs.emenu#gmail.com')";
db.ExecuteQuery<Employee>(insertStatement);
Here insert query is normal sql query and executed using the the LINQ ExecuteQuery method.

Is it possible to return IEnumerable of anonymous objects from DataContext.ExecuteQuery?

I develop a reporting engine where reports are based on templates. Every template has string with SQL query and every report has specific values for SQL query parameters. To render a report I set parameters and call DataContext.ExecuteQuery method to get list of records. But to catch returned columns I have to know their names and have a class with corresponding properties.
Is it possible somehow to return IEnumerable of anonymous objects from DataContext.ExecuteQuery and then determine their properties using Reflection?
I need a LINQ equivalent for SqlDataReader.GetValues.
Thanks!
Until we have C# 4.0 with dynamiс keyword we can use this solution (slightly modified code from an article Executing arbitrary queries in LINQ to SQL by Octavio Hernández Leal):
public static class DataContextExtension
{
public static IEnumerable<Dictionary<string, object>> ExecuteQuery(this DataContext dataContext, string query)
{
using (DbCommand command = dataContext.Connection.CreateCommand())
{
command.CommandText = query;
dataContext.Connection.Open();
using (DbDataReader reader = command.ExecuteReader(CommandBehavior.CloseConnection))
{
while (reader.Read())
{
Dictionary<string, object> dictionary = new Dictionary<string, object>();
for (int i = 0; i < reader.FieldCount; i++)
dictionary.Add(reader.GetName(i), reader.GetValue(i));
yield return dictionary;
}
}
}
}
}
This extension method returns IEnumerable of Dictionary<> objects where keys are names of query columns.
Yes, you can do it.
Please have a look at this snippet.
class Program {
static void Main(string[] args) {
var persons = new Person[]{
new Person{Age=22,Name="John Doe",Id=1},
new Person{Age=23,Name="Jack Smith", Id=2},
new Person{Age=34,Name="Sara Parker", Id=3}
};
var anonData = GetAnonTypes(persons);
foreach (var item in anonData as IEnumerable) {
//use reflection to access propties
}
}
static object GetAnonTypes(IEnumerable<Person> persons) {
var query=from p in persons select new{
Id=p.Id,
Name=p.Name
};
return query;
}
}
public class Person {
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}

Resources