how do I update entity object passed from another class? - c#

This is my query where I'm returning an IEnumerable<CreditCardTransaction> to iterate through.
public partial class CreditCardTransaction
{
public static IEnumerable<CreditCardTransaction> GetUnprocessedTransactions()
{
try
{
using (var context = new SuburbanEntities())
{
return from trans in context.CreditCardTransactions
where trans.IsPublished == false
select trans;
}
}
catch (Exception ex)
{
Logging.Log("An error occurred.", "GetUnprocessedTransactions",Apps.ServicesConfig, ex);
return null;
}
}
}
This is where I am modifying those transactions once I have processed them:
public void ProcessFile()
{
try
{
_client = new TruckServiceClient();
_globalSetting = new GlobalSetting();
var unprocesstransactions = CreditCardTransaction.GetUnprocessedTransactions();
foreach (var creditCardTransaction in unprocesstransactions)
{
creditCardTransaction.IsPublished = ProcessTransaction(creditCardTransaction);
}
}
catch (Exception ex)
{
Logging.Log("An error occurred.", "ProcessCreditCardTransactions.ProcessFile", Apps.RemoteServices, ex);
}
}
I am modifying the transactions here:
creditCardTransaction.IsPublished = ProcessTransaction(creditCardTransaction);
But once I have saved them, can I update the entity directly or do I need to create another method where I pass this information back in?

The problem you don't have access to the context. Here you have some examples how to do:
https://github.com/geersch/EntityFrameworkObjectContext
If you're developing Asp.Net app, you'll have some drawbacks illustreted in this article:
http://dotnetslackers.com/articles/ado_net/Managing-Entity-Framework-ObjectContext-lifespan-and-scope-in-n-layered-ASP-NET-applications.aspx#managing-objectcontext-instantiation

Related

System.MissingMethodException when creating table in sqlite-net-pcl

When calling for this function to create the database, an error occurs System.MissingMethodException: 'Method not found: int SQLite.SQLiteConnection.CreateTable(SQLite.CreateFlags)'
This is where it throws the error during the call for database = new TransmodLocalDB();
App.xaml.cs
public static TransmodLocalDB Database
{
get
{
if (database == null)
{
database = new TransmodLocalDB(0);
}
return database;
}
}
And here is the creation of the tables and the call could not proceed to here.
TransmodLocalDB.cs
public TransmodLocalDB()
{
try
{
database = DependencyService.Get<ISQLite>().GetConnection();
// create the tables
database.CreateTable<Account>(CreateFlags.None);
database.CreateTable<Driver>(CreateFlags.None);
database.CreateTable<Job>(CreateFlags.None);
database.CreateTable<TransportLeg>(CreateFlags.None);
database.CreateTable<Notes>(CreateFlags.None);
database.CreateTable<ImageNote>(CreateFlags.None);
database.CreateTable<Sync>(CreateFlags.None);
database.CreateTable<Enums>(CreateFlags.None);
} catch (Exception ex)
{
var me = ex.Message;
}
}
The exceptions throws before it can create the tables.
Used this library sqlite-net-pcl by Frank A. Krueger latest version 1.6.292

How to overwrite delegated parameters?

How to overwrite delegated parameters
I do have a service with a method like the below:
public static IEnumerable<IntegracaoParoquia> GetMyStuffFromRepo(MainForm form, Decimal myId)
{
IEnumerable<MyStuffClass> stuffCollection = null;
using (var unitOfWork = new UnitOfWork())
{
try
{
unitOfWork.OpenConnection();
stuffCollection = GetRepo().GetStuff(myId, unitOfWork.GetConnection(), unitOfWork.GetTransaction());
}
catch (Exception ex)
{
unitOfWork.Rollback();
LogError(form, ex);
}
}
return stuffCollection;
}
but since a can end with dozen call like this I want to wrap them in a generic call like the below:
private static R CallMyRepoMethod<P, R>(MainForm form, P param, Func<P, IDbConnection, IDbTransaction, R> method)
{
R result = default(R);
using (var unitOfWork = new UnitOfWork())
{
try
{
unitOfWork.OpenConnection();
result = method(param, unitOfWork.GetConnection(), unitOfWork.GetTransaction());
}
catch (Exception ex)
{
unitOfWork.Rollback();
LogError(form, ex);
}
}
return result;
}
public static IEnumerable<IntegracaoParoquia> GetMyStuffFromRepo(MainForm form, Decimal myId)
{
return CallMyRepoMethod<Decimal, IEnumerable<MyStuffClass>>(form, myId, (x,y,z)=>GetRepo().GetStuff(myId, null, null) );
}
The problem is: I want to keep the using inside my delegate (and the provided connection and transaction) but due to the repository method signature. When (x,y,z)=>GetRepo().GetStuff(myId, null, null) is called it passes the null values instead of using the correct values from the delegate.
That's reasonable if you consider the using is not in the scope outside the delegate.
There's any way to get around it or do I need to rewrite it using invoke?

EF returns ExecuteReader requires an open and available Connection. The connection's current state is open. error

I have a lot of classes with this structure as you can see:
public class OrganizationUserRepository : IOrganizationUserRepository
{
private DataContext _ctx;
public OrganizationUserRepository(DataContext ctx)
{
_ctx = ctx;
}
public bool Add(OrganizationUser entity)
{
try
{
_ctx.OrganizationUsers.Add(entity);
_ctx.SaveChanges();
return true;
}
catch (Exception ex)
{
// TODO log this error
return false;
}
}
public bool Edit(OrganizationUser entity)
{
try
{
OrganizationUser Edited = _ctx.OrganizationUsers.Where(i => i.Id == entity.Id).First();
_ctx.Entry(Edited).CurrentValues.SetValues(entity);
_ctx.SaveChanges();
return true;
}
catch (Exception ex)
{
// TODO log this error
return false;
}
}
public bool Remove(string id)
{
try
{
Int64 Id = Int64.Parse(id);
OrganizationUser obj = _ctx.OrganizationUsers.Where(i => i.Id == Id).First();
_ctx.OrganizationUsers.Remove(obj);
_ctx.SaveChanges();
return true;
}
catch (Exception ex)
{
// TODO log this error
return false;
}
}
}
The db context in constructor is injected by ninject .as you can see it just one of my classes .and i have multi classes like this in another services that use a single DB .(WCF Service).But i get this error in my wcf tracelog :
ExecuteReader requires an open and available Connection. The connection's current state is open.
I am using EF code first .
I found this Wrap DbContext db = new DbContext() inusing statement. And i want to know should i use this ,if Yes how can i change my class structure to use using in my code ?
I used public Readonly DbContext .i just remove readonly and everything work fine.

c# transactionscope need rollback only some changes

I'm facing following problem:
In my project, I have done error logging into the same DB, as the application is using. That means, that if error occurs, then in each catch, there is the error stored into DB.
The problem is however, when using transactions. When error occurs, the tran rollbacks, but it also rollbacks the error logged, like in this scenario:
this is public service, used to save client changes.
public UpdateClient(client)
{
try
{
TransactionScope scope0 = new TransactionScope();
// some code
scope0.Complete();
}
catch(Exception ex)
{
Logger.LogException(ex); //log the exception into DB
}
}
this is public service, used to multiple clients changes:
public void UpdateClients(clients)
{
try
{
TransactionScope scope1 = new TransactionScope();
foreach (client c in clients)
{
UpdateClient(c);
}
scope1.Complete();
}
catch (Exception ex)
{
Logger.LogException(ex);
}
}
What happend here is, that if using UpdateClients(), and if error occurs in UpdateClient(), then it is logged into DB in UpdateClient() catch block. The scope0 is rollbacked, and doesnt affect the logged exception. But the scope1 is also rollbacked, and will rollback also the exception stored in DB in the UpdateClient() catch block.
I know, that there are options like store the errors in different DB and so on, but this is unfortunately not acceptible in current state of development.
Is there any way, how to solve this problem without major changes?
You can collect the exceptions while updating and insert them into the db outside the transaction scope:
public UpdateClient(client, bool logErrors = true)
{
try
{
TransactionScope scope0 = new TransactionScope();
// some code
scope0.Complete();
}
catch(Exception ex)
{
Logger.EnlistException(ex); // collect the exception
}
if (logErrors) Logger.WriteEnlistedExceptions();
}
public void UpdateClients(clients)
{
try
{
TransactionScope scope1 = new TransactionScope();
foreach (client c in clients)
{
UpdateClient(c, false);
}
scope1.Complete();
}
catch (Exception ex)
{
Logger.EnlistException(ex);
}
Logger.WriteEnlistedExceptions();
}
public partial class Logger
{
private static List<Exception> _exceptionList = new List<Exception>();
public static void EnlistException(Exception ex)
{
_exceptionList.Add(ex);
}
public static void WriteEnlistedExceptions()
{
foreach(Exception ex in _exceptionList)
LogException(ex);
_exceptionList.Clear();
}
}
This is of course not yet thread safe. The distinction between a call from UpdateClient or UpdateClients can be made by the stack trace of the exception.
As the answers to the question linked by Micky show, there is no way to prevent the rollback by the outer scope.
[EDIT] added logErrors flag
So I found an acceptable solution. The code will be implemented in internal method without transaction and will enlist exception in catch. Then usage is as follows:
internal UpdateClient(client)
{
try
{
// some code
}
catch(Exception ex)
{
Logger.EnlistException(ex); // collect the exception
}
}
public UpdateClient(client)
{
try
{
TransactionScope scope0 = new TransactionScope();
//call internal UpdateClient
/*internal*/ UpdateClient(client);
scope0.Complete();
}
catch(Exception ex)
{
Logger.WriteEnlistedExceptions(ex); // collect and write the exception
}
}
public void UpdateClients(clients)
{
try
{
TransactionScope scope1 = new TransactionScope();
foreach (client c in clients)
{
/*interanl*/ UpdateClient(c);
}
scope1.Complete();
}
catch (Exception ex)
{
Logger.WriteEnlistedExceptions(ex);
}
}
public partial class Logger
{
private static List<Exception> _exceptionList = new List<Exception>();
public static void EnlistException(Exception ex)
{
_exceptionList.Add(ex);
}
public static void WriteEnlistedExceptions()
{
foreach(Exception ex in _exceptionList)
LogException(ex);
_exceptionList.Clear();
}
}

Intermittent issue with Entity Framework

I am using Entity Framework 6.1 version.
I am performing a bulk insert operation with Entity Framework. I am getting an intermittent error with DbContext:
object reference not set to an instance of object" for db context.
Here is my code:
public class ApiTimingDataProvider : IApiTimingDataProvider
{
private ApiTimingDbContext _apiDbContext;
public ApiTimingDataProvider(ApiTimingDbContext apiDbContext)
{
if (apiDbContext == null)
throw new ArgumentNullException("ApiDbContext is Null");
_apiDbContext = apiDbContext;
}
public void InsertApiData(List<ApiTimingModel> apiModelList)
{
try
{
using (var ctx = _apiDbContext)
{
using (var transactionScope = new TransactionScope())
{
// some stuff in dbcontext
ctx.Database.CommandTimeout = 600;
ctx.BulkInsert(apiModelList);
ctx.SaveChanges();
transactionScope.Complete();
}
}
}
catch (Exception ex)
{
throw ex;
}
}
}
Can anyone suggest me the reason for getting the exception?

Categories

Resources