Finding the date of an allday event in google calendar - c#

I have a small C# program to read my Google Calender and return events.
public static IEnumerable<EventEntry> GetAllEvents(CalendarService service, DateTime? startData, DateTime? endData, int nbrToGet)
{
EventQuery query = new EventQuery(); // Create the query object:
if (startData != null)
{
query.StartTime = startData.Value;
}
if (endData != null)
{
query.EndTime = endData.Value;
}
query.SortOrder = CalendarSortOrder.ascending;
query.Uri = new Uri("https://www.google.com/calendar/feeds/" + service.Credentials.Username + "/private/full" + "?max-results=" + nbrToGet.ToString());
EventFeed calFeed = service.Query(query); // Tell the service to query:
return calFeed.Entries.Cast<EventEntry>();
}
I do a foreach on the returned events to display the event details:
foreach (var q in myevents)
{
var one = q.Title.Text;
var two = q.Times.ToList();
if (two.Count > 0)
{
a1 = two[0].StartTime.ToString();
a2 = two[0].EndTime.ToString();
}
else
{
a1 = string.Empty;
a2 = string.Empty;
}
var three = q.Content.Content;
test.Add(new MyCalendarData { Title = one, StartTime = a1, EndTime = a2, Content = three });
}
On all day events, there is no Start time or End time. Is there a way to find the date associated with the event?

Related

Data migration script really slows down after 300 rows

I am currently migrating data from an old MS Infopath based application to an asp.net core app. I have written a .net console app to read from four tables (tblcreated, tblPDI, tblHistory, tblDekadenplanung, tblAdv) containing the old data, manipulating some attributes (e.g. dates) and writing it back to the new table structures (table VehicleFiles, Deliveries, CustomerPayment, comments). Because VehicleFiles holds the foreign keys of the deliveries and customer payment data, i have to save them to DB to get the ID and then store the ID in the vehiclefiles row, which might cause a high load due to the 2 separate write processes). Its 30.000 rows in total.
When I have the migration app running on my web server to avoid latency, it starts very fast, processing around 20 rows per second. But as soon as it hits the 300 rows mark it gradually starts to slow down. At the 25000 mark it took about 3 to 4 minutes to process 10 rows yesterday. I just post the code, maybe someone will find obvious flaws or memory leaks in my code and give me notice.
static void Main(string[] args) {
var logRepository = LogManager.GetRepository(Assembly.GetEntryAssembly());
XmlConfigurator.Configure(logRepository, new FileInfo("log4net.config"));
log.InfoFormat("Running as {0}", WindowsIdentity.GetCurrent().Name);
var Configuration = new ConfigurationBuilder().SetBasePath(Path.Combine(AppContext.BaseDirectory)).AddJsonFile("appsettings.json", optional: true).Build();
var serviceProvider = new ServiceCollection().AddDbContext < AutolineContext > ...
// ...Removed bc password
var autolineContext = serviceProvider.GetRequiredService < AutolineContext > ();
var samContext = serviceProvider.GetRequiredService < SAMContext > ();
var luxWebContext = serviceProvider.GetRequiredService < LUX_WEB_SAMContext > ();
var tblCreated = samContext.TblCreated.OrderBy(x = >x.Id).ToList();
var tblPDIAll = samContext.TblPdi.ToList();
var tblHistoryAll = samContext.TblTerminHistorie.ToList();
var tblDekadenplanungAll = samContext.TblDekadenplanung.ToList();
var tblAdvAll = samContext.TblAdV.ToList();
var tblPDI = new TblPdi();
var tblHistory = new TblTerminHistorie();
var tblDekadenplanung = new TblDekadenplanung();
var tblAdv = new TblAdV();
int counter = 0;
var begin = DateTime.Now;
var lastTime = DateTime.Now;
Deliveries delivery = new Deliveries();
CustomerPayments customerPayments = new CustomerPayments();
foreach(var item in tblCreated) {
counter++;
if (counter % 10 == 0) {
Console.WriteLine("\nNächstes Element: " + item.Id + "\nVerarbeitet: " + counter + "\nSekunden seit Beginn: " + (DateTime.Now - begin).TotalSeconds + "\nDauer letzte Zehn: " + (DateTime.Now - lastTime).Seconds);
}
VehicleFiles vf = luxWebContext.OrderNumbers.Where(x = >x.CommissionNumber == item.Kommissionsnummer).Select(x = >x.FkVehicleFileNavigation).SingleOrDefault();
delivery = new Deliveries();
customerPayments = new CustomerPayments();
tblPDI = tblPDIAll.SingleOrDefault(x = >x.Kommissionsnummer == item.Kommissionsnummer);
tblHistory = tblHistoryAll.Where(x = >x.Kommissionsnummer == item.Kommissionsnummer).OrderBy(x = >x.CreationDate).LastOrDefault();
tblDekadenplanung = tblDekadenplanungAll.SingleOrDefault(x = >x.Kommissionsnummer == item.Kommissionsnummer);
tblAdv = tblAdvAll.SingleOrDefault(x = >x.Kommissionsnummer == item.Kommissionsnummer);
// PDI
delivery.Pdichecker = tblPDI.PdiPruefer;
delivery.Pdistatus = tblPDI.PdiOk == "OK" ? "1": "";
if (!string.IsNullOrEmpty(tblPDI.Pdi)) {
log.Info("Speichere PDI-Datum: " + DateTime.ParseExact(tblPDI.Pdi, "dd/MM/yyyy", CultureInfo.InvariantCulture));
delivery.Pdidate = DateTime.ParseExact(tblPDI.Pdi, "dd/MM/yyyy", CultureInfo.InvariantCulture);
}
DateTime dateValue;
if (!string.IsNullOrEmpty(tblPDI.ZurReinigung) && DateTime.TryParse(tblPDI.ZurReinigung.Replace("h", ":"), out dateValue)) {
log.Info("Speichere Reinigung-Datum: " + DateTime.Parse(tblPDI.ZurReinigung.Replace("h", ":")));
delivery.ForCleaning = DateTime.Parse(tblPDI.ZurReinigung.Replace("h", ":"));
}
// Registrierung
delivery.PlateMounted = tblPDI.Montiert == "OK";
delivery.RegistrationStatus = tblPDI.AnmeldungOk == "Ok";
// Auslieferung
if (tblHistory != null && !string.IsNullOrEmpty(tblHistory.DeliveryDate)) {
log.Info("Speichere Plan-Delivery-Datum: " + DateTime.Parse(tblHistory.DeliveryDate.Split(" ")[0]));
delivery.PlanDeliveryDate = DateTime.Parse(tblHistory.DeliveryDate.Split(" ")[0]);
}
if (!string.IsNullOrEmpty(item.DatumAuslieferung)) {
log.Info("Speichere Delivery-Datum: " + DateTime.Parse(item.DatumAuslieferung));
delivery.DeliveryActual = DateTime.Parse(item.DatumAuslieferung);
}
delivery.DeliveryPerson = tblDekadenplanung.Auslieferer;
if (tblDekadenplanung.Teamleiter != null) delivery.TeamLead = DateTime.Parse(tblDekadenplanung.Teamleiter);
delivery.CreationDate = DateTime.Now;
delivery.CreationUser = "MigrationJob";
// Zahlungsart
decimal value;
customerPayments.Value1 = Decimal.TryParse(tblDekadenplanung.Betrag, out value) ? Convert.ToDecimal(tblDekadenplanung.Betrag) : default;
customerPayments.Value2 = Decimal.TryParse(tblDekadenplanung.Betrag2, out value) ? Convert.ToDecimal(tblDekadenplanung.Betrag2) : default;
customerPayments.PaymentTyp1 = string.IsNullOrEmpty(customerPayments.PaymentTyp1) ? PaymentMethodConverter(tblDekadenplanung.Zahlungsart) : null;
customerPayments.PaymentTyp2 = string.IsNullOrEmpty(customerPayments.PaymentTyp2) ? PaymentMethodConverter(tblDekadenplanung.Zahlungsart2) : null;
customerPayments.CreationDate = DateTime.Now;
customerPayments.CreationUser = "MigrationJob";
customerPayments.LastEditedBy = tblDekadenplanung.LastUser;
if (!string.IsNullOrEmpty(tblDekadenplanung.UpdateDate)) customerPayments.LastEditedDate = DateTime.Parse(tblDekadenplanung.UpdateDate);
log.Info("Schreibe CreationDate: " + item.Creationdate.Value.ToUniversalTime());
vf.CreationDate = item.Creationdate.HasValue ? item.Creationdate.Value.ToUniversalTime() : new DateTime();
vf.CreationUser = item.AnlageUser;
vf.Active = item.Archive == "False" ? false: true;
vf.Concluded = item.Abgeschlossen == "Ja" ? true: false;
vf.ConclusionDate =
default; // Nicht gesetzt im alten SAM
vf.HolUndBringDauer = item.HolBringDauer != "0" ? Convert.ToInt32(item.HolBringDauer) : default;
if (delivery.DeliveryActual.HasValue) vf.HolUndBringEnde = delivery.DeliveryActual.Value.AddMonths(Convert.ToInt32(item.HolBringDauer)).AddDays( - 1);
// Kommentare
if (!string.IsNullOrEmpty(tblDekadenplanung.KommentarAus) && tblDekadenplanung.KommentarAus != "-") {
CommentsSam deliveryComment = new CommentsSam {
FkVehicleFile = vf.PkVehicleFile,
Comment = tblDekadenplanung.KommentarAus,
User = "Sys",
CommentType = "Delivery",
Date = DateTime.Now
};
luxWebContext.Add(deliveryComment);
}
if (!string.IsNullOrEmpty(tblPDI.KommentarLog)) {
CommentsSam pdiComment = new CommentsSam {
FkVehicleFile = vf.PkVehicleFile,
Comment = tblPDI.KommentarLog,
User = "Sys",
CommentType = "PDI",
Date = DateTime.Now
};
luxWebContext.Add(pdiComment);
}
if (!string.IsNullOrEmpty(tblAdv.KommentarZah)) {
CommentsSam advComment = new CommentsSam {
FkVehicleFile = vf.PkVehicleFile,
Comment = tblAdv.KommentarZah,
User = "Sys",
CommentType = "ADV",
Date = DateTime.Now
};
luxWebContext.Add(advComment);
}
try {
luxWebContext.Add(delivery);
luxWebContext.Add(customerPayments);
luxWebContext.SaveChanges();
vf.FkDelivery = delivery.PkDelivery;
vf.FkCustomerPayment = customerPayments.PkCustomerPayment;
luxWebContext.Update(vf);
log.Info("Daten erfolgreich geschrieben. VehicleFile-ID: " + vf.PkVehicleFile);
lastTime = DateTime.Now;
delivery = null;
customerPayments = null;
}
catch(Exception e) {
log.Error("Fehler beim Schreiben der Daten: " + e);
}
}
The process memory in visual studio 2019 is capped at ~261 mb. This is what the diagnosis looks like in the first 6 mins:
I have found this blog post that deals with the same problem but I don't know how to apply it to my specific case:
https://weblog.west-wind.com/posts/2014/dec/21/gotcha-entity-framework-gets-slow-in-long-iteration-loops
One of the issues with your code
foreach(var item in tblCreated) {
// ..
VehicleFiles vf = luxWebContext.OrderNumbers.Where(x = >x.CommissionNumber == item.Kommissionsnummer).Select(x = >x.FkVehicleFileNavigation).SingleOrDefault();
assuming luxWebContext is your EF context. For each item in tblCreated you fire a query to SQL server. This is a huge performance hit.
Rather fetch your data before your for loop and convert it to a Dictionary or Lookup.
// Before loop
var orderNumerbsByCommsionNumber = luxWebContext.OrderNumbers.ToLookup(x => x.CommissionNumber)
// Or ToDictionary(x => x.CommissionNumber) if the CommissionNumber is unique.
foreach(var item in tblCreated) {
// ..
VehicleFiles vf = orderNumerbsByCommsionNumber[item.Kommissionsnummer].Select(x => x.FkVehicleFileNavigation).SingleOrDefault();
You can do the same for every where/first/single in your loops. In your example:
tblPDI = tblPDIAll.SingleOrDefault(x = >x.Kommissionsnummer == item.Kommissionsnummer);
tblHistory = tblHistoryAll.Where(x = >x.Kommissionsnummer == item.Kommissionsnummer).OrderBy(x = >x.CreationDate).LastOrDefault();
tblDekadenplanung = tblDekadenplanungAll.SingleOrDefault(x = >x.Kommissionsnummer == item.Kommissionsnummer);
tblAdv = tblAdvAll.SingleOrDefault(x = >x.Kommissionsnummer == item.Kommissionsnummer);
if you want you can batch commit, add this line to the end of your loop
if(counter % 100 = 0)
{
luxWebContext.SaveChanges(); // Or async version
}
This commits the changes to the database every time the counter is divisible by 100.
Alright, I figured out how to solve this issue. I added the disposal and new creation of my luxWebContext on every foreach iteration with the using keyword, which disposes the luxWebContext automatically after leaving the brackets. Looks like this:
foreach(var item in tblCreated) {
counter++;
using(var luxWebContext = new LUX_WEB_SAMContext(optionsBuilder.Options)) {
if (counter % 100 == 0) {
Console.WriteLine("\nNächstes Element: " + item.Id + "\nVerarbeitet: " + counter + "\nSekunden seit Beginn: " + (DateTime.Now - begin).TotalSeconds + "\nDauer letzte Zehn: " + (DateTime.Now - lastTime).Milliseconds);
lastTime = DateTime.Now;
}
...

C# Solr query - how to only get future dates?

I have a search method that queries Solr for event items. I need to modify it to only get events where the date has not already passed (i.e. Where(x => x.EventDate.Date >= DateTime.Now.Date), but I'm not sure how to add this because I'm not very familiar with Solr. Here's my search function:
public SearchQueryResults Search(string keywords, int page,int perPage, List<Guid> contentTypeFilters, List<Guid> otherFilters, ISortBuilder<SearchResultItem> sortBuilder)
{
var searchFilters = new List<IPredicateBuilder<SearchResultItem>>()
{
new IsSearchablePredicateBuilder()
};
if (contentTypeFilters.Any())
{
var contentTypePredicateBuilder = new ContentTypePredicateBuilder();
contentTypePredicateBuilder.ContentTypes = contentTypeFilters;
searchFilters.Add(contentTypePredicateBuilder);
}
if (otherFilters.Any())
{
var tagFilterBuilder = new TagsAndPredicateBuilder(otherFilters,_sitecoreContext);
searchFilters.Add(tagFilterBuilder);
}
if (string.IsNullOrWhiteSpace(keywords))
{
keywords = "";
}
SearchRequest searchRequest = new SearchRequest();
var queryParams = new Dictionary<string, string>() { };
queryParams.Add("q", keywords);
searchRequest.QueryParameters = queryParams;
searchRequest.SortBy = "";
searchRequest.SortOrder = "";
SearchQuery<SearchResultItem> queryArguments = new SearchQuery<SearchResultItem>();
queryArguments.FilterBuilders = searchFilters;
queryArguments.Page = page;
queryArguments.PerPage = perPage;
queryArguments.FacetsBuilder = new SearchFacetBuilder<SearchResultItem>();
queryArguments.SearchRequest = searchRequest;
queryArguments.IndexName = _indexName;
if (string.IsNullOrWhiteSpace(keywords))
{
queryArguments.QueryBuilders =new List<IPredicateBuilder<SearchResultItem>>();
}
else
{
queryArguments.QueryBuilders = new[] { new KeywordPredicateBuilder<SearchResultItem>(new[] { keywords }) };
}
queryArguments.SortBuilder = sortBuilder;
try
{
var results = _searchManager.GetResults<SearchResultItem>(queryArguments);
SearchQueryResults queryResults = new SearchQueryResults();
queryResults.ResultItems = results.Results;
queryResults.CurrentPage = page;
queryResults.TotalResults = Int32.Parse(results.TotalResults.ToString());
queryResults.TotalPages = (queryResults.TotalResults + perPage - 1) / perPage; ;
return queryResults;
}
catch (Exception exc)
{
Sitecore.Diagnostics.Log.Error("Error with FilteredSearch, could be a loss of connection to the SOLR server: " + exc.Message, this);
return null;
}
}
and here is how it's being called:
Results = _searchService.Search(searchTerm, CurrentPage - 1, 10, contentTypes, searchFilters,
new GenericSortBuilder<SearchResultItem>(q => q.OrderByDescending(r => r.SearchDate)));
How do I add in date filtering so that it only returns items where the date is in the future?
I would add filter query to the list of existing ones filtering the date field. On the documentation page, I was able to find information about fluent API, which could help here
Query.Field("date").From(DateTime.Now)
I'm not C# developer, that this code could have some mistakes, but I think the main idea is clear what needs to be done.

C# (Xamarin iOS) How to loop son data on Custom UITableViewCell?

Any Help will be appreaciated :) Thank you in advance
I tried to loop other object inside of the function and its working but on this, it can't loop. Help. this is rush, and I'm not that familiar with creating iOS app.
public override void ViewDidLoad()
{
base.ViewDidLoad();
using (var web = new WebClient())
{
var url = "http://www.creativeinterlace.com/smitten/maintenance/api/feeds/get-miss-location/101";
json = web.DownloadString(url);
}
json = json.Replace("{\"location\":", "").Replace("}]}", "}]");
var ls = JArray.Parse(json);
if (ls.Count != 0)
{
foreach (var x in ls)
{
var name = x.SelectToken("location");
name1 = Convert.ToString(name);
var loc = x.SelectToken("address");
loc1 = Convert.ToString(loc);
var time = x.SelectToken("time_ago");
time1 = Convert.ToString(time);
locations = new List<Locations>
{
new Locations
{
shopname = name1,
address= loc1,
time = time1
},
};
}
nmtable.Source = new LocationSource(locations);
nmtable.RowHeight = 60;
nmtable.ReloadData();
}
}
You initialize the locations every time in the loop,so the list updates with only the newest object. You should initialize the list outside of the loop , and add object every time.
locations = new List<Locations>();
if (ls.Count != 0)
{
foreach (var x in ls)
{
var name = x.SelectToken("location");
name1 = Convert.ToString(name);
var loc = x.SelectToken("address");
loc1 = Convert.ToString(loc);
var time = x.SelectToken("time_ago");
time1 = Convert.ToString(time);
locations.Add(new Locations{ shopname = name1,address= loc1,time = time1});
};
}

EF copying entities with Navigation properties

I have a requirement to copy objects along with its navigation properties and create new objects. Following is what I did:
// get parent location's work availability template
WorkAvailTemplate workAvailTemplate = locationsFromDb.Where(l => l.Location2 == null).SingleOrDefault().WorkAvailTemplates.First();
foreach (var loc in locationsToAddOrUpdate)
{
// add op-hours template only for the new locations (the ID sometimes can be -1
if (loc.LocationId < 1)
{
if (workAvailTemplate != null)
{
WorkAvailTemplate wt = new WorkAvailTemplate
{
Location = loc,
CreatedBy = this.CurrentUser.Id,
CreatedDate = DateTime.Now,
NumberOfRotations = workAvailTemplate.NumberOfRotations,
ActiveStatus = workAvailTemplate.ActiveStatus
};
ClientContext.WorkAvailTemplates.Add(wt);
var workAvailTemplateDays = workAvailTemplate.WorkAvailTemplateDays.ToList();
foreach (WorkAvailTemplateDay d in workAvailTemplateDays)
{
WorkAvailTemplateDay wd = new WorkAvailTemplateDay
{
WorkAvailTemplate = wt,
WeekNumber = d.WeekNumber,
DayNumber = d.DayNumber,
ChangedBy = this.CurrentUser.Id,
ChangedDate = DateTime.Now
};
ClientContext.WorkAvailTemplateDays.Add(wd);
foreach (var r in d.WorkAvailTemplateTimeRanges)
{
WorkAvailTemplateTimeRange wr = new WorkAvailTemplateTimeRange
{
WorkAvailTemplateDay = wd,
StartTime = r.StartTime,
EndTime = r.EndTime,
ChangedBy = this.CurrentUser.Id,
ChangedDate = DateTime.Now
};
ClientContext.WorkAvailTemplateTimeRanges.Add(wr);
}
}
}
}
}
I'm sure there's a better way to do this rather than creating new objects. Any thoughts?
Earlier, when I did this for a single Location object creation, i did as follow and it works fine.
WorkAvailTemplate workAvailTemplate = (from wat in ClientContext.WorkAvailTemplates
where wat.FkLocationId == newLocation.FkParentLocationId
select wat).SingleOrDefault();
if (workAvailTemplate != null)
{
workAvailTemplate.Location = newLocation;
ClientContext.WorkAvailTemplates.Add(workAvailTemplate);
var workAvailTemplateDays = from watd in ClientContext.WorkAvailTemplateDays
join wat in ClientContext.WorkAvailTemplates on watd.FkWorkAvailTemplateId equals wat.WorkAvailTemplateId
where wat.FkLocationId == newLocation.FkParentLocationId
select watd;
foreach (WorkAvailTemplateDay d in workAvailTemplateDays)
{
d.WorkAvailTemplate = workAvailTemplate;
var workAvailTimeRangePerDay = (from r in ClientContext.WorkAvailTemplateTimeRanges.AsEnumerable()
where r.FkWorkAvailTemplateDayId == d.WorkAvailTemplateDayId
select this.f(r, d, newLocation));
ClientContext.WorkAvailTemplateDays.Add(d);
ClientContext.WorkAvailTemplateTimeRanges.AddRange(workAvailTimeRangePerDay);
}
}
But when I did the same for mutiple objects in a loop, it only creates for the first Location object. I don't get any errors, but simply they don't get created for others.

Parsing Complex XML with C# LINQ

I am using c# and LINQ in a script transformation in VS2012 to parse a complex xml soap message. I cannot figure out how to loop through the xml and get all the elements that I want in a single row. The xml is below. This is only a portion of what is returned. There are 48 intervals for each item and generally 5-6 items.
<return>
<item>
<interval>
<intervalDate>
<day>8</day>
<month>7</month>
<year>2016</year>
</intervalDate>
<intervalTime>
<hours>0</hours>
<militaryTime>true</militaryTime>
<minutes>0</minutes>
<seconds>0</seconds>
</intervalTime>
<laborType>forecasted</laborType>
<volume>0.0</volume>
</interval>
<interval>
<intervalDate>
<day>8</day>
<month>7</month>
<year>2016</year>
</intervalDate>
<intervalTime>
<hours>0</hours>
<militaryTime>true</militaryTime>
<minutes>30</minutes>
<seconds>0</seconds>
</intervalTime>
<laborType>forecasted</laborType>
<volume>0.0</volume>
</interval>
<jobCode>1</jobCode>
<jobName>SERVER</jobName>
</item>
<item>
<interval>
<intervalDate>
<day>8</day>
<month>7</month>
<year>2016</year>
</intervalDate>
<intervalTime>
<hours>0</hours>
<militaryTime>true</militaryTime>
<minutes>0</minutes>
<seconds>0</seconds>
</intervalTime>
<laborType>forecasted</laborType>
<volume>0.0</volume>
</interval>
<interval>
<intervalDate>
<day>8</day>
<month>7</month>
<year>2016</year>
</intervalDate>
<intervalTime>
<hours>0</hours>
<militaryTime>true</militaryTime>
<minutes>30</minutes>
<seconds>0</seconds>
</intervalTime>
<laborType>forecasted</laborType>
<volume>0.0</volume>
</interval>
<jobCode>50</jobCode>
<jobName>Cashier</jobName>
</item>
I need to output the data into 5 columns, datetime, laborType, laborVolume, laborJobCode, and laborJobName.
laborDateTime|laborType|laborVolume|laborJobCode|laborJobName
2016-08-07 00:00:00.000|forecasted|0|1|SERVER
2016-08-07 00:30:00.000|forecasted|0|1|SERVER
2016-08-07 01:00:00.000|forecasted|0|1|SERVER
2016-08-07 01:30:00.000|forecasted|0|1|SERVER
I have not been able to find any examples online that show how to do this. If I loop through Interval, I return the expected number of rows but have no way of getting the JobCode and JobName.
public override void CreateNewOutputRows()
{
/*
Add rows by calling the AddRow method on the member variable named "<Output Name>Buffer".
For example, call MyOutputBuffer.AddRow() if your output was named "MyOutput".
*/
String content = Variables.XMLString;
XElement xdoc = XElement.Parse(content);
var Interval = from interval in xdoc.Descendants("interval")
select new
{
laborIntervalDay = interval.Element("intervalDate").Element("day").Value,
laborIntervalMonth = interval.Element("intervalDate").Element("month").Value,
laborIntervalYear = interval.Element("intervalDate").Element("year").Value,
laborIntervalHour = interval.Element("intervalTime").Element("hours").Value,
laborIntervalMinutes = interval.Element("intervalTime").Element("minutes").Value,
laborIntervalSeconds = interval.Element("intervalTime").Element("seconds").Value,
laborIntervalMilitary = interval.Element("intervalTime").Element("militaryTime").Value,
laborType = interval.Element("laborType").Value,
laborVolume = interval.Element("volume").Value
};
foreach (var q in Interval)
{
try
{
DateTime dtBusinessDate = new DateTime(Convert.ToInt32(q.laborIntervalYear), Convert.ToInt32(q.laborIntervalMonth), Convert.ToInt32(q.laborIntervalDay), Convert.ToInt32(q.laborIntervalHour), Convert.ToInt32(q.laborIntervalMinutes), Convert.ToInt32(q.laborIntervalSeconds));
OUTLaborBuffer.AddRow();
OUTLaborBuffer.laborDateTime = dtBusinessDate;
OUTLaborBuffer.laborType = Convert.ToString(q.laborType);
OUTLaborBuffer.laborVolume = Convert.ToDouble(q.laborVolume);
//OUTLaborBuffer.laborJobCode = Convert.ToInt64(p.laborJobCode);
//OUTLaborBuffer.laborJobName = p.laborJobName;
}
catch (Exception ex)
{
MessageBox.Show("Error Message: " + ex.Message + " Message Detail: " + ex.StackTrace);
}
}
}
I've also tried looping through Labor and Interval but this is not correct because it is assigning the JobCode/JobName of the current iteration of Labor to all intervals. If there are 5 items then I end up with 5x the expected rows.
var Interval = from interval in xdoc.Descendants("interval")
select new
{
laborIntervalDay = interval.Element("intervalDate").Element("day").Value,
laborIntervalMonth = interval.Element("intervalDate").Element("month").Value,
laborIntervalYear = interval.Element("intervalDate").Element("year").Value,
laborIntervalHour = interval.Element("intervalTime").Element("hours").Value,
laborIntervalMinutes = interval.Element("intervalTime").Element("minutes").Value,
laborIntervalSeconds = interval.Element("intervalTime").Element("seconds").Value,
laborIntervalMilitary = interval.Element("intervalTime").Element("militaryTime").Value,
laborType = interval.Element("laborType").Value,
laborVolume = interval.Element("volume").Value
};
var Labor = from item in xdoc.Descendants("item")
select new
{
laborJobCode = item.Element("jobCode").Value,
laborJobName = item.Element("jobName").Value,
};
foreach (var p in Labor)
{
// Save check information
try
{
foreach (var q in Interval)
{
try
{
DateTime dtBusinessDate = new DateTime(Convert.ToInt32(q.laborIntervalYear), Convert.ToInt32(q.laborIntervalMonth), Convert.ToInt32(q.laborIntervalDay), Convert.ToInt32(q.laborIntervalHour), Convert.ToInt32(q.laborIntervalMinutes), Convert.ToInt32(q.laborIntervalSeconds));
OUTLaborBuffer.AddRow();
OUTLaborBuffer.laborDateTime = dtBusinessDate;
OUTLaborBuffer.laborType = Convert.ToString(q.laborType);
OUTLaborBuffer.laborVolume = Convert.ToDouble(q.laborVolume);
OUTLaborBuffer.laborJobCode = Convert.ToInt64(p.laborJobCode);
OUTLaborBuffer.laborJobName = p.laborJobName;
}
catch (Exception ex)
{
MessageBox.Show("Error Message: " + ex.Message + " Message Detail: " + ex.StackTrace);
}
}
}
catch (Exception ex)
{
MessageBox.Show("Error Message: " + ex.Message + " Message Detail: " + ex.StackTrace);
}
}
}
I have found some examples online showing of complex xml being parsed like below:
var Labor = from item in xdoc.Descendants("item")
select new
{
laborJobCode = item.Element("jobCode").Value,
laborJobName = item.Element("jobName").Value,
laborInterval = (from interval in xdoc.Descendants("interval")
select new
{
laborIntervalDay = interval.Element("intervalDate").Element("day").Value,
laborIntervalMonth = interval.Element("intervalDate").Element("month").Value,
laborIntervalYear = interval.Element("intervalDate").Element("year").Value,
laborIntervalHour = interval.Element("intervalTime").Element("hours").Value,
laborIntervalMinutes = interval.Element("intervalTime").Element("minutes").Value,
laborIntervalSeconds = interval.Element("intervalTime").Element("seconds").Value,
laborIntervalMilitary = interval.Element("intervalTime").Element("militaryTime").Value,
laborType = interval.Element("laborType").Value,
laborVolume = interval.Element("volume").Value
})
};
The examples I've found with this structure are outputting ToList and I can't figure out how to output the descendants of interval in this format. Do you have any idea how this can be done?
Something like this should do the trick:
public dynamic OUTLaborBuffer;
public dynamic Variables;
public void CreateNewOutputRows()
{
String content = Variables.XMLString;
XElement data = XElement.Parse(content);
foreach (var item in data.XPathSelectElements("//item"))
{
var jobCode = item.Element("jobCode").Value;
var jobName = item.Element("jobName").Value;
foreach (var interval in item.XPathSelectElements("//interval"))
{
var laborIntervalDay = interval.Element("intervalDate").Element("day").Value;
var laborIntervalMonth = interval.Element("intervalDate").Element("month").Value;
var laborIntervalYear = interval.Element("intervalDate").Element("year").Value;
var laborIntervalHour = interval.Element("intervalTime").Element("hours").Value;
var laborIntervalMinutes = interval.Element("intervalTime").Element("minutes").Value;
var laborIntervalSeconds = interval.Element("intervalTime").Element("seconds").Value;
var laborIntervalMilitary = interval.Element("intervalTime").Element("militaryTime").Value;
var laborType = interval.Element("laborType").Value;
var laborVolume = interval.Element("volume").Value;
DateTime dtBusinessDate = new DateTime(Convert.ToInt32(laborIntervalYear), Convert.ToInt32(laborIntervalMonth), Convert.ToInt32(q.laborIntervalDay), Convert.ToInt32(laborIntervalHour), Convert.ToInt32(laborIntervalMinutes), Convert.ToInt32(laborIntervalSeconds));
OUTLaborBuffer.AddRow();
OUTLaborBuffer.laborDateTime = dtBusinessDate;
OUTLaborBuffer.laborType = Convert.ToString(laborType);
OUTLaborBuffer.laborVolume = Convert.ToDouble(laborVolume);
OUTLaborBuffer.laborJobCode = Convert.ToInt64(jobCode);
OUTLaborBuffer.laborJobName = jobName;
}
}
}
feel free to change XPathSelectElements back to Descendants
I was able to solve this by using parent to get the JobCode and JobName while looping through intervals. I based it off of on this example: Linq on Complex XML
Here is the code I ended up with:
public override void CreateNewOutputRows()
{
/*
Add rows by calling the AddRow method on the member variable named "<Output Name>Buffer".
For example, call MyOutputBuffer.AddRow() if your output was named "MyOutput".
*/
String content = Variables.XMLString;
XElement xdoc = XElement.Parse(content);
var Interval = from interval in xdoc.Descendants("interval")
select new
{
laborJobCode = interval.Parent.Element("jobCode").Value,
laborJobName = interval.Parent.Element("jobName").Value,
laborIntervalDay = interval.Element("intervalDate").Element("day").Value,
laborIntervalMonth = interval.Element("intervalDate").Element("month").Value,
laborIntervalYear = interval.Element("intervalDate").Element("year").Value,
laborIntervalHour = interval.Element("intervalTime").Element("hours").Value,
laborIntervalMinutes = interval.Element("intervalTime").Element("minutes").Value,
laborIntervalSeconds = interval.Element("intervalTime").Element("seconds").Value,
laborIntervalMilitary = interval.Element("intervalTime").Element("militaryTime").Value,
laborType = interval.Element("laborType").Value,
laborVolume = interval.Element("volume").Value
};
foreach (var q in Interval)
{
try
{
DateTime dtBusinessDate = new DateTime(Convert.ToInt32(q.laborIntervalYear), Convert.ToInt32(q.laborIntervalMonth), Convert.ToInt32(q.laborIntervalDay), Convert.ToInt32(q.laborIntervalHour), Convert.ToInt32(q.laborIntervalMinutes), Convert.ToInt32(q.laborIntervalSeconds));
OUTLaborBuffer.AddRow();
OUTLaborBuffer.laborDateTime = dtBusinessDate;
OUTLaborBuffer.laborType = Convert.ToString(q.laborType);
OUTLaborBuffer.laborVolume = Convert.ToDouble(q.laborVolume);
OUTLaborBuffer.laborJobCode = Convert.ToInt64(q.laborJobCode);
OUTLaborBuffer.laborJobName = Convert.ToString(q.laborJobName);
}
catch (Exception ex)
{
MessageBox.Show("Error Message: " + ex.Message + " Message Detail: " + ex.StackTrace);
}
}
}

Categories

Resources