How to roll back queries in C#? - linq

I have list of delete queries & I execute them with this code:
using (var ctx = new ApplicationDbContext(schemaName))
{
foreach (var item in queries)
{
ctx.Database.ExecuteSqlCommand(item);
}
}
I want to commit all the delete queries, but I want to roll back if there is some error in any of the queries.
How to do roll back in the above scenario?

Try to use TransactionScope
using System.Transactions;
try
{
using (var scope = new TransactionScope())
{
using (var ctx = new ApplicationDbContext(schemaName))
{
foreach (var item in queries)
{
ctx.Database.ExecuteSqlCommand(item);
}
}
scope.Complete();
}
}
catch (Exception ex)
{
}

Related

Parallel call to Elasticsearch in c#

I am trying to make a parallel call to Elasticsearch index for multiple queries and aggregate the result, using Parallel.ForEach.
My code:
private static List<SearchResponse<dynamic>> SearchQueryInParallel(string indexName, string lang, string[] eQueries)
{
var result = new List<SearchResponse<dynamic>>();
var exceptions = new ConcurrentQueue<Exception>();
object mutex = new object();
try
{
Parallel.ForEach(eQueries,
() => new SearchResponse<dynamic>()
, (q, loopState, subList) =>
{
var x = LowlevelClient.Search<SearchResponse<dynamic>>(indexName, $"article_{lang}", q);
subList = x;
return subList;
}, subList =>
{
lock (result)
result.Add(subList);
}
);
}
catch (AggregateException ae)
{
foreach (var e in ae.InnerExceptions)
{
exceptions.Enqueue(e);
}
}
if (exceptions.ToList().Any())
{
//there are exceptions, do something with them
//do something?
}
return result;
}
The problem I am facing is that sublist in the above case is long.
It gives me the following error:
Can not convert from SearchResponse to long.
The same thing is working when I used without multithreading, the code is:
var items = new List<dynamic>();
var searchResponse = lowLevelClient.Search<SearchResponse<dynamic>>(elasticIndexName, $"article_{languageCode.ToLowerInvariant()}", query);
foreach (var document in searchResponse.Body.Documents)
{
items.Add(document);
}
Any help, please? If somebody has any other way to achieve the parallel call and aggregating data from returned values would be greatly appreciated.

Get properties of empty linq statement

Is there a way of looping through the properties of the underlining result of the linq statement when the linq statement contains no elements?
I would like to create a DataTable and add the individual properties as columns, but it seems this can only be done when the linq statement contains items. Please see my current code below
private static void GetProperties<T>(IEnumerable<T> query)
{
DataTable dt = new DataTable();
PropertyInfo[] queryInfo = null;
foreach (var item in query)
{
if (queryInfo == null)
{
queryInfo = item.GetType().GetProperties();
foreach (var info in queryInfo)
{
dt.Columns.Add(info.Name);
}
}
DataRow dr = dt.NewRow();
foreach (PropertyInfo pi in queryInfo)
{
dr[pi.Name] = pi.GetValue(item, null) ?? DBNull.Value;
}
dt.Rows.Add(dr);
}
}
Desired code, or something similar:
private static void GetProperties<T>(IEnumerable<T> query)
{
DataTable dt = new DataTable();
PropertyInfo[] queryInfo = null;
queryInfo = query.FirstOrDefault().GetType().GetProperties();
foreach (var info in queryInfo)
{
dt.Columns.Add(info.Name);
}
foreach (var item in query)
{
DataRow dr = dt.NewRow();
foreach (PropertyInfo pi in queryInfo)
{
dr[pi.Name] = pi.GetValue(item, null) ?? DBNull.Value;
}
dt.Rows.Add(dr);
}
}
I would always like the DataTable to contain the columns, even if the linq statement contains no items.
I am open to any suggestions.
Thanks.
I suspect all you're looking for it:
PropertyInfo[] queryInfo = typeof(T).GetProperties();
In other words, get the properties from the generic type argument rather than for a particular instance of that type.

Getting data from a Linq DbContext to a stored procedure

I am calling a stored procedure using Linq. I want to put that data in list. Can anyone help me how to do this? You can see my code here:
public getidrange(int startrange, int endrange)
{
List<string> idRange = new List<string>();
string Conn = System.Configuration.ConfigurationManager.ConnectionStrings["mydbconnection"].ToString();
GetIDRangeDataContext GetIdRange = new GetIDRangeDataContext(Conn);
try
{
GetIdRange.sp_GetIdRange(startRange, endRange);
}
catch(Exception ex)
{
}
return idRange;
}
I just did the following to and it worked .
try
{
var res = GetIdRange.sp_GetIdRange(startRange, endRange);
foreach (var ids in res)
{
idRange.Add(ids.NewIDAnalisi.ToString());
objGetIdRangeResults.success = true;
}

Oracle fom Nhibernate batch insert not work

<property name="adonet.batch_size">100</property>
here is some code:
using (var session = SessionFactory.NHSessionFactory.OpenStatelessSession())
{
using (var tx = session.BeginTransaction())
{
try
{
foreach (var entity in entities)
{
session.Insert(entity);
}
tx.Commit();
}
catch (Exception ex)
{
}
}
}
the same code,and the same config.but oracle is not batch insert.
I try to add
<property name="adonet.factory_class">NHibernate.AdoNet.OracleDataClientBatchingBatcherFactory,NHibernate</property>
throw null object.
Stateless sessions do not use batching.
That's it.

How can I use Linq instead of foreach to get items out of a nested set?

I have multiple nested foreach loops that do some processing, how can I convert this expression to Linq?
slug.Text = "";
foreach (var script in slugItem.script) {
foreach (var body in script.body) {
foreach (var vo in body.vo) {
foreach (var content in vo.content) {
foreach (var text in content.text) {
slug.Text = string.Format("{0}\n{1}", slug.Text, text.Value);
} } } } }
slug.Text = string.Join("\n", slugItem.script.SelectMany(i=>i.body)
.SelectMany(i=>i.vo)
.SelectMany(i=>i.content)
.SelectMany(i=>i.text)
.SelectMany(i=>i.Value));
Why use Linq, what would it add? I would however use a StringBuilder
var slugtext = new StringBuilder();
foreach (var script in slugItem.script)
{
foreach (var body in script.body)
{
foreach (var vo in body.vo)
{
foreach (var content in vo.content)
{
foreach (var text in content.text)
{
slugText.AppendLine(text.Value);
}
}
}
}
}
slug.Text = slugText.ToString();

Resources