OutOfMemory Exception for Parallel.ForEach - c#

I have a console application which runs as 32 bit process(we cant change it to 64 bit) and is throwing Out of memory Exception. We traced minor Memory leak(related to Entity Framework repository) in a downstream process but with that too application should not cross 2 GB memory.
One thing i want to understand is sometimes application processes 2500 records while other times it fails at 100.(Server memory utilization is under 60% when this application is running
I am using Parallel.forEach and controlling number of threads to 4 using ParallelOptions. Can anybody suggest making the application on a single thread may by any chance resolve the problem.
(The application didn't fail in any lower environment but only in production and giving us a very hard time).
Below is the code snippet.
Thanks In Advance,
Rohit
protected override void Execute(IEnumerable<PlanPremiumDetails> argument)
{
if (argument.Any())
{
var EnrollmentRequests = argument.GroupBy(c => c.CaseNumber).ToList();
SelectedPlanPremiumDetails request;
EnrollmentResponse enrollmentResponse;
bool taskStatus;
Common.Status.TotalAutoEnrollRecords = EnrollmentRequests.Count;
Common.StartTimer();
Action<IGrouping<int,PlanPremiumDetails>> processRequest = eRequest =>
{
int caseNumber;
List<EnrolledIndividual> enrolledIndividuals;
try
{
string errorMessage;
caseNumber = eRequest.Key;
if (eRequest.Any(f => f.FailedMCOEnrollmentId > 0))
{
request = FailedMcoRequest(eRequest, caseNumber);
enrollmentResponse = InvokeEnrollment(request);
if (enrollmentResponse.OverallStatus == false && enrollmentResponse.ErrorInformationMA != null)
{
StringBuilder messages = new StringBuilder();
if (enrollmentResponse.ErrorInformationMA.ErrorInformationPostMcaps != null)
{
messages.Append(enrollmentResponse.ErrorInformationMA.ErrorInformationPostMcaps.Message);
Exception innerExp = enrollmentResponse.ErrorInformationMA.ErrorInformationPostMcaps.InnerException;
if (innerExp != null)
{
// messages.Append(enrollmentResponse.ErrorInformationMA.ErrorInformationPostMcaps.InnerException.Message);
do
{
messages.Append(innerExp.Message);
innerExp = innerExp.InnerException;
}
while (innerExp != null);
}
}
else
{
if (enrollmentResponse.ErrorInformationMA != null && enrollmentResponse.ErrorInformationMA.InnerErrorInfo != null)
{
foreach (var msg in enrollmentResponse.ErrorInformationMA.InnerErrorInfo)
{
messages.Append( string.Format(#"ErrorCode: {0}, ErrorMessage: {1} ",msg.ErrorCode,msg.ErrorMessage));
}
}
}
errorMessage = Convert.ToString(messages);
Common.Errors.Add(new Exception(String.Format(ConfigurationManager.AppSettings["FailedEnrollErrorText"], caseNumber, errorMessage), enrollmentResponse.ErrorInformationMA.ErrorInformationPostMcaps));
taskStatus = GenerateTask(eRequest, caseNumber, false, errorMessage);
if (taskStatus)
{
UpdateTriggerStatus(caseNumber, "Y");
}
else
{
UpdateTriggerStatus(caseNumber, "N");
Common.Errors.Add(new Exception(String.Format(ConfigurationManager.AppSettings["FailedEnrollErrorText"], caseNumber, "Task Creation")));
}
}
else
{
Common.Status.Success = (Common.Status.Success + 1);
UpdateTriggerStatus(caseNumber, "Y");
}
}
else
{
enrolledIndividuals = eRequest.Select(p => new EnrolledIndividual
{
IndividualId = p.IndividualId,
EdgTraceId = p.EdgTraceId,
EDGNumber = p.EDGNumber
}).ToList();
request = new SelectedPlanPremiumDetails()
{
EmployerId = 0,
CaseNumber = caseNumber,
CallBackId = Common.ApplicationName,
SourceSystem = EnrollmentLibrary.SourceSystem.MAAUTOASSIGN,
AutoAssignMCOIndividuals = enrolledIndividuals
};
enrollmentResponse = InvokeEnrollment(request);
if (enrollmentResponse.OverallStatus == false && enrollmentResponse.ErrorInformationMA != null)
{
StringBuilder messages = new StringBuilder();
if (enrollmentResponse.ErrorInformationMA.ErrorInformationPostMcaps != null)
{
messages.Append(enrollmentResponse.ErrorInformationMA.ErrorInformationPostMcaps.Message);
Exception innerExp = enrollmentResponse.ErrorInformationMA.ErrorInformationPostMcaps.InnerException;
if (innerExp != null)
{
// messages.Append(enrollmentResponse.ErrorInformationMA.ErrorInformationPostMcaps.InnerException.Message);
do
{
messages.Append(innerExp.Message);
innerExp = innerExp.InnerException;
}
while (innerExp != null);
}
}
else
{
if (enrollmentResponse.ErrorInformationMA != null && enrollmentResponse.ErrorInformationMA.InnerErrorInfo.Count != null)
{
foreach (var msg in enrollmentResponse.ErrorInformationMA.InnerErrorInfo)
{
messages.Append(string.Format(#"ErrorCode: {0}, ErrorMessage: {1} ", msg.ErrorCode, msg.ErrorMessage));
}
}
}
errorMessage = Convert.ToString(messages);
Common.Errors.Add(new Exception(String.Format(ConfigurationManager.AppSettings["AutoEnrollErrorText"], caseNumber, errorMessage), enrollmentResponse.ErrorInformationMA.ErrorInformationPostMcaps));
}
else
{
// Update status to be saved in InterfaceSummary table.
Common.Status.Success = (Common.Status.Success + 1);
}
}
}
catch(Exception ex)
{
Common.Errors.Add(new Exception(String.Format(ConfigurationManager.AppSettings["AutoEnrollErrorText"], eRequest.Key, ex.Message), ex));
}
};
}
int dParallelism = Convert.ToInt32(ConfigurationManager.AppSettings["DegreeofParallelism"]);
Parallel.ForEach(EnrollmentRequests,
new ParallelOptions() { MaxDegreeOfParallelism = dParallelism > 0 ? dParallelism : 1 },
processRequest);

Related

A second operation started on this context before a previous asynchronous

hai im new on c# actually i have an issue with my code which i couldnt find the error. I making a controller which i can see the details that user sumbit. When im debug it say that " Use 'await' to ensure that any asynchronous operations". i try to put await every each of line but doesnt working.
plus in my cases i dont use for each method
here is my code :-
public async Task<ActionResult> Details(int id, string currentFilter)
{
try
{
BizRepMaster bizRepmaster = _bizRepMasterService.Find(id);
if (bizRepmaster.RepCountry != null)
ViewBag.BizCountry = _countryMasterService.Find(bizRepmaster.RepCountry).tCountry;
else
ViewBag.BizCountry = "";
if (bizRepmaster.RepState == null)
{
ViewBag.State = "";
}
else
{
if (bizRepmaster.RepState == "Oth")
{
ViewBag.State = "Others";
}
else
{
ViewBag.State = GetStateName(bizRepmaster.RepCountry, bizRepmaster.RepState);
}
}
if (bizRepmaster.MailState == null)
{
ViewBag.MailState = "";
}
else
{
if (bizRepmaster.RepState == "Oth")
{
ViewBag.MailState = "Others";
}
else
{
ViewBag.MailState = GetBizStateName(bizRepmaster.RepCountry, bizRepmaster.MailState);
}
}
ViewBag.AMNationality = _countryMasterService.GetCountryMaster()
.Where(a => a.tISO == bizRepmaster.RepNationality).Single().tCountry;
ViewBag.AMIdType = _idTypeService.GetIdTypes()
.Where(a => a.TypeID == bizRepmaster.RepIdType).Single().LabelName;
if (bizRepmaster.DialCode != null)
{
ViewBag.DialCode = _unitOfWorkAsync.Repository<Country>().Find(bizRepmaster.DialCode).tDialCode;
}
if (bizRepmaster.NatureOfBusiness != null)
{
}
ViewBag.AMResType = _unitOfWorkAsync.Repository<ResidencyType>().Find(bizRepmaster.RepResidencyType).LabelName;
ViewBag.AMJobType = _unitOfWorkAsync.Repository<SenderJobType>().Find(bizRepmaster.RepJobType).LabelName;
ViewBag.StateList = new SelectList(_stateService.GetStates(), "nId", "tStateDesc");
if (bizRepmaster.IdType != null)
ViewBag.IdTypeList = _idTypeService.Find(Convert.ToInt32(bizRepmaster.RepIdType)).LabelName;
ViewBag.CreatedUserName = _userProfileService.GetUserProfile().Where(a => a.UserID == Convert.ToInt32(bizRepmaster.CreatedBy)).Single().LoginId;
if (bizRepmaster.ApprovedBy != null)
{
ViewBag.ApprovedUserName = _userProfileService.GetUserProfile().Where(a => a.UserID == Convert.ToInt32(bizRepmaster.ApprovedBy)).Single().LoginId;
}
if (bizRepmaster.LastUpdatedBy != null)
{
ViewBag.LastUpdatedName = _userProfileService.GetUserProfile().Where(a => a.UserID == Convert.ToInt32(bizRepmaster.LastUpdatedBy)).Single().LoginId;
}
if (bizRepmaster.LastApprovedBy != null)
{
ViewBag.LastApprovedName = _userProfileService.GetUserProfile().Where(a => a.UserID == Convert.ToInt32(bizRepmaster.LastApprovedBy)).Single().LoginId;
}
ViewBag.SenderId1 = bizRepmaster.SenderId;
return View("_BizRepDetails", bizRepmaster);
}
catch (Exception ex)
{
return PartialView("_ErrorMessageView");
}
}

How to handle New transaction is not allowed because there are other threads running in the session for multiple calls or to save as list of Entities

Hi I am using Entity Framework Code First, I have a collection of Entities that need to be saved, but I have my EF Repository created as below
public T Create(T item)
{
try
{
if (ufb != null && ufb.CurrentUser != null)
{
SetValue("CreatedByUserId", item, ufb.CurrentUser.Id);
SetValue("UpdatedByUserId", item, ufb.CurrentUser.Id);
}
SetValue("DateCreated", item, DateTime.Now);
SetValue("DateUpdated", item, DateTime.Now);
var newEntry = this.DbSet.Add(item);
this.Context.Database.Log = message => LogHandler.LogInfo(1111, message);
try
{
this.Context.SaveChanges();
}
catch (Exception ex)
{
LogHandler.LogInfo(2501, ex.Message);
}
BuildMetaData(item, true, true);
return newEntry;
}
catch (DbEntityValidationException dbEx)
{
// http://forums.asp.net/t/2014382.aspx?Validation+failed+for+one+or+more+entities+See+EntityValidationErrors+property+for+more+details+
string msg = string.Empty;
foreach (var validationErrors in dbEx.EntityValidationErrors)
{
foreach (var validationError in validationErrors.ValidationErrors)
{
msg += validationError.PropertyName;
msg += "---";
msg += validationError.ErrorMessage;
msg += "||";
}
}
throw new Exception("7777 CREATE EntityValidationErrors: " + msg);
}
}
My calling method is as below:
public List<VehicleInfo> Create(List<VehicleInfo> vehicleInfos, string Entity, int EntityId)
{
bool vehicleExists = false; List<VehicleInfo> newVehicleInfos = null;
if ((vehicleInfos != null) && (vehicleInfos.Count > 0))
{
newVehicleInfos = new List<VehicleInfo>();
foreach (VehicleInfo vehicleInfo in vehicleInfos)
{
vehicleExists = false;
if (vehicleInfo != null)
{
vehicleExists = this.VehicleExists(vehicleInfo.VehicleId, Entity, EntityId);
vehicleInfo.Entity = Entity;
vehicleInfo.EntityId = EntityId;
VehicleInfo v = this.UnitOfWork.VehicleInfoRepository.Create(vehicleInfo);
newVehicleInfos.Add(v);
}
}
}
return newVehicleInfos;
}
Hence when I am calling repositories create method for multiple times, its throwing me the above error, any help or suggestion would be very helpful, please thank you.
void BuildMetaDataNoThread(object item, bool active, bool isNew = false)
{
if (item.GetType() != typeof(JsonObject))
{
var dm = new DataAccessUnitOfWork(Constants.DefaultConnection);
var qtype = item.GetType();
if (qtype.BaseType.BaseType != null)
{
if ((isNew && qtype.BaseType.Name == typeof(ModelBase).Name) | qtype.BaseType.BaseType.Name == typeof(ModelBase).Name)
{
Thread.Sleep(500);
//collect data
var element = (ModelBase)item;
element.BuildMetaData(DataRequestType.CurrentItem);
var records = ModelBase.MetaData;
ModelBase.MetaData = new List<ModelRecord> { };
if (records == null) return;
foreach (ModelRecord r in records)
{
if (r!=null)
{
var jsr = new JavaScriptSerializer();
//object meta = r;
object rdata = r.Data;
var type = rdata.GetType();
var token = type.BaseType.Name;
List<string> include = r.Include;
// Cycle-through clieanup of models to be encoded into Json Data.
// this helper eliminates infinate relations by including records specified
// by a list of strings
if (include.Where(x => x.Contains("CreatedByUser")).Count() == 0)
include.Add("CreatedByUser");
if (include.Where(x => x.Contains("UpdatedByUser")).Count() == 0)
include.Add("UpdatedByUser");
var data = ClassCloner.CollectData(rdata, include);
List<string> tags = ClassCloner.CollectTags(data);
string _tags = "";
tags.ForEach((xtm) =>
{
_tags += xtm + ',';
});
var json = jsr.Serialize(data);
int id = 0;
//get identity
foreach (var prop in type.GetProperties())
{
if (id == 0)
{
foreach (var cp in prop.CustomAttributes)
{
if (cp.AttributeType.Name == "KeyAttribute")
{
var _id = ((Dictionary<string, object>)data)[prop.Name];
id = (int)_id;
break;
}
}
}
else { break; }
}
var query = dm.JsonObjectRepository.GetAll();
var key = "_" + token;
var _data = (Dictionary<string, object>)data;
var ExistingMetaData = (from x in query where x.SourceKey == key && x.SourceId == id select x).FirstOrDefault();
if (ExistingMetaData != null)
{
if (_data.ContainsKey("DateUpdated")) ExistingMetaData.Date = (DateTime)_data["DateUpdated"];
ExistingMetaData.SourceData = data;
ExistingMetaData.Encode();
ExistingMetaData.Active = active;
ExistingMetaData.SearchTags = _tags;
dm.JsonObjectRepository.Update(ExistingMetaData);
}
else
{
var newData = new JsonObject
{
Active = true,
Date = (DateTime)_data["DateUpdated"],
SourceData = data,
SourceId = id,
SourceKey = key,
SearchTags = _tags,
TargetKey = "GlobalSearchMetaData"
};
newData.Encode();
dm.JsonObjectRepository.Create(newData);
}
}
}
}
}
}
}
void BuildMetaData(object dataRecord, bool active, bool isNew)
{
new Thread((item) => { BuildMetaDataNoThread(item, active, isNew); }).Start(dataRecord);
}

System.OutOfMemoryException in C# when Generating huge amount of byte[] objects

I'm using this code to modify a pdf tmeplate to add specific details to it,
private static byte[] GeneratePdfFromPdfFile(byte[] file, string landingPage, string code)
{
try
{
using (var ms = new MemoryStream())
{
using (var reader = new PdfReader(file))
{
using (var stamper = new PdfStamper(reader, ms))
{
string _embeddedURL = "http://" + landingPage + "/Default.aspx?code=" + code + "&m=" + eventCode18;
PdfAction act = new PdfAction(_embeddedURL);
stamper.Writer.SetOpenAction(act);
stamper.Close();
reader.Close();
return ms.ToArray();
}
}
}
}
catch(Exception ex)
{
File.WriteAllText(HttpRuntime.AppDomainAppPath + #"AttachmentException.txt", ex.Message + ex.StackTrace);
return null;
}
}
this Method is being called from this Method:
public static byte[] GenerateAttachment(AttachmentExtenstion type, string Contents, string FileName, string code, string landingPage, bool zipped, byte[] File = null)
{
byte[] finalVal = null;
try
{
switch (type)
{
case AttachmentExtenstion.PDF:
finalVal = GeneratePdfFromPdfFile(File, landingPage, code);
break;
case AttachmentExtenstion.WordX:
case AttachmentExtenstion.Word:
finalVal = GenerateWordFromDocFile(File, code, landingPage);
break;
case AttachmentExtenstion.HTML:
finalVal = GenerateHtmlFile(Contents, code, landingPage);
break;
}
return zipped ? _getZippedFile(finalVal, FileName) : finalVal;
}
catch(Exception ex)
{
return null;
}
}
and here is the main caller,
foreach (var item in Recipients)
{
//...
//....
item.EmailAttachment = AttachmentGeneratorEngine.GenerateAttachment(_type, "", item.AttachmentName, item.CMPRCode, _cmpTmp.LandingDomain, _cmpTmp.AttachmentZip.Value, _cmpTmp.getFirstAttachment(item.Language, item.DefaultLanguage));
}
The AttachmentGeneratorEngine.GenerateAttachment method is being called approx. 4k times, because I'm adding a specific PDF file from a PDF template for every element in my List.
recently I started having this exception:
Exception of type 'System.OutOfMemoryException' was thrown. at System.IO.MemoryStream.ToArray()
I already implemented IDisposible in the classes and and I made sure that all of them are being released.
Note: it was running before very smoothely and also I double checked the system's resources - 9 GB is used out of 16 GB, so I had enough memory available.
==========================================
Update:
Here is the code that loops through the list
public static bool ProcessGroupLaunch(string groupCode, int customerId, string UilangCode)
{
CampaignGroup cmpGList = GetCampaignGroup(groupCode, customerId, UilangCode)[0];
_campaigns = GetCampaigns(groupCode, customerId);
List<CampaignRecipientLib> Recipients = GetGroupRcipientsToLaunch(cmpGList.ID, customerId);
try
{
foreach (var item in _campaigns)
item.Details = GetCampaignDetails(item.CampaignId.Value, UilangCode);
Stopwatch stopWatch = new Stopwatch();
#region single-threaded ForEach
foreach (var item in Recipients)
{
CampaignLib _cmpTmp = _campaigns.FirstOrDefault(x => x.CampaignId.Value == item.CampaignId);
bool IncludeAttachment = _cmpTmp.IncludeAttachment ?? false;
bool IncludeAttachmentDoubleBarrel = _cmpTmp.IncludeAttachmentDoubleBarrel ?? false;
if (IncludeAttachment)
{
if (_cmpTmp.AttachmentExtension.ToLower().Equals("doc") || (_cmpTmp.AttachmentExtension.ToLower().Equals("docx")))
_type = AttachmentGeneratorEngine.AttachmentExtenstion.Word;
else if (_cmpTmp.AttachmentExtension.ToLower().Equals("ppt") || (_cmpTmp.AttachmentExtension.ToLower().Equals("pptx")))
_type = AttachmentGeneratorEngine.AttachmentExtenstion.PowePoint;
else if (_cmpTmp.AttachmentExtension.ToLower().Equals("xls") || (_cmpTmp.AttachmentExtension.ToLower().Equals("xlsx")))
_type = AttachmentGeneratorEngine.AttachmentExtenstion.Excel;
else if (_cmpTmp.AttachmentExtension.ToLower().Equals("pdf"))
_type = AttachmentGeneratorEngine.AttachmentExtenstion.PDF;
else if (_cmpTmp.AttachmentExtension.ToLower().Equals("html"))
_type = AttachmentGeneratorEngine.AttachmentExtenstion.HTML;
}
//set "recpient" details
item.EmailFrom = _cmpTmp.EmailFromPrefix + "#" + _cmpTmp.EmailFromDomain;
item.EmailBody = GetChangedPlaceHolders((_cmpTmp.getBodybyLangCode(string.IsNullOrEmpty(item.Language) ? item.DefaultLanguage : item.Language, item.DefaultLanguage)), item.ID, _cmpTmp.CustomerId.Value, _cmpTmp.CampaignId.Value);
if (item.EmailBody.Contains("[T-LandingPageLink]"))
{
//..
}
if (item.EmailBody.Contains("[T-FeedbackLink]"))
{
//..
}
if (item.EmailBody.Contains("src=\".."))
{
//..
}
//set flags to be used by the SMTP Queue and Scheduler
item.ReadyTobeSent = true;
item.PickupReady = false;
//add attachment to the recipient, if any.
if (IncludeAttachment)
{
item.AttachmentName = _cmpTmp.getAttachmentSubjectbyLangCode(string.IsNullOrEmpty(item.Language) ? item.DefaultLanguage : item.Language, item.DefaultLanguage) + "." + _cmpTmp.AttachmentExtension.ToLower();
try
{
if (_type == AttachmentGeneratorEngine.AttachmentExtenstion.PDF || _type == AttachmentGeneratorEngine.AttachmentExtenstion.WordX || _type == AttachmentGeneratorEngine.AttachmentExtenstion.Word)
item.EmailAttachment = AttachmentGeneratorEngine.GenerateAttachment(_type, "", item.AttachmentName, item.CMPRCode, _cmpTmp.LandingDomain, _cmpTmp.AttachmentZip.Value, _cmpTmp.getFirstAttachment(item.Language, item.DefaultLanguage));
else item.EmailAttachment = AttachmentGeneratorEngine.GenerateAttachment(_type, value, item.AttachmentName, item.CMPRCode, _cmpTmp.LandingDomain, _cmpTmp.AttachmentZip.Value);
item.AttachmentName = _cmpTmp.AttachmentZip.Value ? (_cmpTmp.getAttachmentSubjectbyLangCode(string.IsNullOrEmpty(item.Language) ? item.DefaultLanguage : item.Language, item.DefaultLanguage) + ".zip") :
_cmpTmp.getAttachmentSubjectbyLangCode(string.IsNullOrEmpty(item.Language) ? item.DefaultLanguage : item.Language, item.DefaultLanguage) + "." + _cmpTmp.AttachmentExtension.ToLower();
}
catch (Exception ex)
{
}
}
else
{
item.EmailAttachment = null;
item.AttachmentName = null;
}
}
#endregion
stopWatch.Stop();
bool res = WriteCampaignRecipientsLaunch(ref Recipients);
return res;
}
catch (Exception ex)
{
Recipients.ForEach(i => i.Dispose());
cmpGList.Dispose();
Recipients = null;
cmpGList = null;
return false;
}
finally
{
Recipients.ForEach(i => i.Dispose());
cmpGList.Dispose();
Recipients = null;
cmpGList = null;
}
}

Get the count of resultsets/Tables returned from dapper .QueryMultiple Method

While using Dapper for multiple Query:
var result = sqlConnection.QueryMultiple(query, Parameters, commandType: commandType);
How can i get the table count returned from query? It has two overloaded implementation of .Read() method, which each time called, moves to next available result set (No result.Count() property). Eventually i want to put that number in a loop to iterate as many time as number of tables returned from query.
var reader = this.DbConnection.QueryMultipleAsync(sql, Params, commandType: CommandType.StoredProcedure).Result;
if(reader.IsConsumed == false)
{
DeviceTypeReport = reader?.ReadAsync<dynamic>().Result;
}
This is probably what you are looking for hope it helps.
This is probably what you are looking for hope it helps.
List<dynamic> data = new List<dynamic>();
while (reader.IsConsumed == false)
{
data.Add(await reader?.ReadAsync<dynamic>());
}
int totalRecordSet = data.Count;
public List NotificationExecuteMultiple(OutdoorRequest objreq, IConfiguration configuration)
{
var lst = new List<dynamic>();
using (DbConnection connection = new MySqlConnection(configuration.GetConnectionString("SquareHrConn")))
{
using (var dr = connection.QueryMultiple(ProcedureName, GetParamenter(objreq), commandType: CommandType.StoredProcedure))
{
while (dr.IsConsumed == false)
{
lst.Add(dr.Read());
}
}
}
return lst;
}
Consider the follwoing method to cover all cases
protected List<object> ExecuteMultiQuery<A, B, C, D, E, F, G, H, I, J>(string procedureName, DynamicParameters param = null)
{
List<object> result = new List<object>();
using (var connection = new SqlConnection(ConnectionManager.ConnectionString))
{
try
{
connection.Open();
using (var multi = connection.QueryMultiple(procedureName, param, commandType: CommandType.StoredProcedure, commandTimeout: 120))
{
var varA = multi.Read<A>();
if (varA != null) { result.Add(varA.ToList()); }
var varB = multi.Read<B>();
if (varB != null) { result.Add(varB.ToList()); }
var varC = multi.Read<C>();
if (varC != null) { result.Add(varC.ToList()); }
var varD = multi.Read<D>();
if (varD != null) { result.Add(varD.ToList()); }
var varE = multi.Read<E>();
if (varE != null) { result.Add(varE.ToList()); }
var varF = multi.Read<F>();
if (varF != null) { result.Add(varF.ToList()); }
var varG = multi.Read<G>();
if (varG != null) { result.Add(varG.ToList()); }
var varH = multi.Read<H>();
if (varH != null) { result.Add(varH.ToList()); }
var varI = multi.Read<I>();
if (varI != null) { result.Add(varI.ToList()); }
var varJ = multi.Read<J>();
if (varJ != null) { result.Add(varJ.ToList()); }
//if (varA != null) { result.Add(varA.ToList()); }
//if (resultSets > 1) { result.Add(multi.Read<B>().ToList()); }
//if (resultSets > 2) { result.Add(multi.Read<C>().ToList()); }
//if (resultSets > 3) { result.Add(multi.Read<D>().ToList()); }
//if (resultSets > 4) { result.Add(multi.Read<E>().ToList()); }
//if (resultSets > 5) { result.Add(multi.Read<F>().ToList()); }
//if (resultSets > 6) { result.Add(multi.Read<G>().ToList()); }
//if (resultSets > 7) { result.Add(multi.Read<H>().ToList()); }
//if (resultSets > 8) { result.Add(multi.Read<I>().ToList()); }
//if (resultSets > 9) { result.Add(multi.Read<J>().ToList()); }
return result;
}
}
catch (System.Exception e)
{
string message = e.Message;
}
}
return result;
}

savechanges() saving one entity and not other

A weird situation has struck me this code was running successfully two days back, but i dont know why its not running as before now :
public static void ChangeStatus(int sessionID, int? participantID, Guid? temporaryParticipantID, int statustypeID)
{
using (EMSEntities entities = new EMSEntities())
using (TransactionScope ts = new TransactionScope())
{
try
{
SessionParticipant sessionParticipant = null;
CurrentSessionSeatsStatu sessionCurrentStatus = null;
if (participantID != null)
{
sessionParticipant = entities.SessionParticipants
.Where(a => a.SessionID == sessionID && a.ParticipantID == participantID)
.FirstOrDefault();
}
else if (temporaryParticipantID != null)
{
sessionParticipant = entities.SessionParticipants
.Where(a => a.SessionID == sessionID && a.TemporaryParticipantID == temporaryParticipantID)
.FirstOrDefault();
}
if (sessionParticipant != null)
{
sessionParticipant.StatusTypeID = statustypeID; // Status Changed here
}
**if (sessionParticipant.StatusTypeID == 2) // verified status
{
sessionCurrentStatus = entities.CurrentSessionSeatsStatus
.Where(a => a.SessionID == sessionID)
.FirstOrDefault();
if (sessionCurrentStatus.SeatsLeft > 0)
{
sessionCurrentStatus.SeatsLeft = sessionCurrentStatus.SeatsLeft - 1;
}
}**
entities.SaveChanges();
ts.Complete();
}
catch (Exception ex)
{
ts.Dispose();
}
}
}
The problem is that changes(in StatusTypeID) for sessionParticipant are not saved in database but sessionCurrentStatus changes are !
no error thrown nothing !
Edit: I have discovered that the change in sessionparticipant is happening in all cases except when the status is changed to verified.
ie. when the other table viz. sessioncurrentstatus is updated in the if block.
That is whenever it goes in this if block(bold in code) the problem takes place.
Finally i found the problem and i think its because of the below code however it would be good if someone can explain the exact reason:
EMS.DAL.DALHelper.AttachAndSaveChanges(sessionParticipant, System.Data.EntityState.Modified); // the position of this code line can be found in the below code
below is the code which called the ChangesStatus method:
protected void ddlStatuses_SelectedIndexChanged(object sender, EventArgs e)
{
for (int i = 0; i < gridViewEvents.VisibleRowCount; i++)
{
if (gridViewEvents.Selection.IsRowSelected(i))
{
EMS.DAL.SessionParticipant sessionParticipant = (EMS.DAL.SessionParticipant)gridViewEvents.GetRow(i);
EMS.DAL.Session session = EMS.DAL.DALHelper.GetSessionById(sessionParticipant.SessionID);
EMS.DAL.DALHelper.ChangeStatus(sessionParticipant.SessionID, sessionParticipant.ParticipantID, sessionParticipant.TemporaryParticipantID, Convert.ToInt32(ddlStatuses.SelectedItem.Value));
if (ddlStatuses.SelectedItem.Value == "2" || ddlStatuses.SelectedItem.Value == "3") // if accepted or rejected
{
if (ddlStatuses.SelectedItem.Value == "2") // verified/accepted
{
EMS.DAL.DALHelper.SendMail("Congratulations! your participation for " + session.Name + " event has been confirmed.", "", sessionParticipant.Email, "");
// AT THIS POINT THE 'sessionParticipant' did not have the changed status which was set in the ChangeStatus method
sessionParticipant.IsNotified = true;
EMS.DAL.DALHelper.AttachAndSaveChanges(sessionParticipant, System.Data.EntityState.Modified); // culprit as per me
List<EMS.DAL.SessionAttendanceList> attendanceList = EMS.DAL.DALHelper.GetSessionAttendanceList(session.ID);
attendanceList.ForEach(a =>
{
EMS.DAL.AttendanceListDetail attendanceListDetail = a.AttendanceListDetails.Where(p => p.ParticipantID == sessionParticipant.ParticipantID).FirstOrDefault();
if (attendanceListDetail == null)
{
attendanceListDetail.AttendanceListID = a.ID;
attendanceListDetail.ParticipantID = sessionParticipant.ParticipantID.Value;
attendanceListDetail.IsPresent = false;
EMS.DAL.DALHelper.AttachAndSaveChanges(attendanceListDetail, System.Data.EntityState.Added);
}
});
}
else if (ddlStatuses.SelectedItem.Value == "3") // denied/rejected
{
EMS.DAL.DALHelper.SendMail("Your participation for " + session.Name + " event has been denied.", "", sessionParticipant.Email, "");
sessionParticipant.IsNotified = true;
EMS.DAL.DALHelper.AttachAndSaveChanges(sessionParticipant, System.Data.EntityState.Modified);
List<EMS.DAL.SessionAttendanceList> attendanceList = EMS.DAL.DALHelper.GetSessionAttendanceList(session.ID);
attendanceList.ForEach(a =>
{
EMS.DAL.AttendanceListDetail attendanceListDetail = a.AttendanceListDetails.Where(p => p.ParticipantID == sessionParticipant.ParticipantID).FirstOrDefault();
if (attendanceListDetail != null)
{
EMS.DAL.DALHelper.AttachAndSaveChanges(attendanceListDetail, System.Data.EntityState.Deleted);
}
});
}
}
else
{
List<EMS.DAL.SessionAttendanceList> attendanceList = EMS.DAL.DALHelper.GetSessionAttendanceList(session.ID);
attendanceList.ForEach(a =>
{
EMS.DAL.AttendanceListDetail attendanceListDetail = a.AttendanceListDetails.Where(p => p.ParticipantID == sessionParticipant.ParticipantID).FirstOrDefault();
if (attendanceListDetail != null)
{
EMS.DAL.DALHelper.DeleteAttendanceListDetail(attendanceListDetail);
}
});
attendanceList.ForEach(a =>
{
EMS.DAL.DALHelper.DeleteSessionAttendanceList(a);
});
}
}
}
gridViewEvents.DataBind();
RefreshSeats();
}

Categories

Resources