Item's property inside a list changes value from EF source - is there a way to 'detach' it? - entity-framework

I have a list and this list is being populated thru loop. Each loop gets a collection directly from DB. The problem is that when it gets CaseNo(PK) that has the same CaseNo existing in the list and I changed the value of one of the property, the item that has the same CaseNo which is already in the list also changes.
ex. caseNo 1234, proc code = OTH
then I add another item which I get from DB again. but this time I programatically change the proc code, the item in the list above also changes to that value also.
I do not want that to happen because it is not the same Case in the record because a Case can have different type of pro code as its category.
I get that it is changing because it is detecting that it is the same item as the one in the list but I need to add the same case number in the list as a separate item because the proc code is different. Is there a way I can treat it as different entity as the one in the list?
Ex. of data
1.)CaseNO 123
Proc code OTH
2.) CaseNO 123
Proc code OTH
but I need it to be:
1.)CaseNO 123
Proc code DSP
1.)CaseNO 123
Proc code OTH
it goes wrong when this line is executed.
adrCase.ProcCode = "DSP";
then the item in the list (_adrMasterList) if there is any with the same case no, changes its proc code too to "DSP".
here is my code:
private void GenerateReport(string caseCoordinatorID) //LGF 08012011 ADR-59: add case coordinator - add parameter
{
var dispositions = FileMaintenanceBusiness.Instance.GetManyDispositionInfobyKeyword(_selectedProcCode, "ProcCode");
var adrDispos = FileMaintenanceBusiness.Instance.GetAllADRDispositionInfoList();
var calendarActivities = FileMaintenanceBusiness.Instance.GetManyCalendarActivityInfobyKeyword(_selectedProcCode, "ProcCode");
var adrCalActivities = FileMaintenanceBusiness.Instance.GetAllADRCalendars();
var otherActivities = FileMaintenanceBusiness.Instance.GetManyOtherActivities(_selectedProcCode, "ProcCode");
var adrOtherActivities = FileMaintenanceBusiness.Instance.GetAllADROtherActivities();
_adrMasterList.Clear();
if (_selectedProcCode == "ALL")
{
var dispositionALL = FileMaintenanceBusiness.Instance.GetAllDispositionInfoList();
var adrDisposALL = FileMaintenanceBusiness.Instance.GetAllADRDispositionInfoList();
var calendarActivitiesALL = FileMaintenanceBusiness.Instance.GetAllCalendarActivityInfoList();
var adrCalActivitiesALL = FileMaintenanceBusiness.Instance.GetAllADRCalendars();
var otherActivitiesALL = FileMaintenanceBusiness.Instance.GetAllOtherActivities();
var adrOtherActivitiesALL = FileMaintenanceBusiness.Instance.GetAllADROtherActivities();
if (dispositionALL != null && adrDisposALL != null)//dispos
{
foreach (var dispo in dispositionALL)
{
foreach (var adrDispo in adrDisposALL)
{
if (dispo.DispositionID == adrDispo.DispositionID)
{
var adrCase = FileMaintenanceBusiness.Instance.GetADRMasterInfobyKeyword(adrDispo.CaseNo, "CaseNo");
if (adrCase != null)
{
adrCase.ProcCode = "DSP";
adrCase.ProcDateString = dispo.ProcDate.HasValue ? dispo.ProcDate.Value.ToShortDateString() : string.Empty;
//LGF 08012011 ADR-59: add case coordinator - add CaseCoordinatorFilter
//if (!_adrMasterList.Contains(adrCase) && CaseCoordinatorFilter(caseCoordinatorID, adrCase.CaseNo))
// _adrMasterList.Add(adrCase);
if (CaseCoordinatorFilter(caseCoordinatorID, adrCase.CaseNo))
_adrMasterList.Add(adrCase);
}
}
}
}
}
if (calendarActivitiesALL != null && adrCalActivitiesALL != null)//cals
{
foreach (var cal in calendarActivitiesALL)
{
foreach (var adrCal in adrCalActivitiesALL)
{
if (cal.CalendarItemID == adrCal.CalendarItemID)
{
var adrCase = FileMaintenanceBusiness.Instance.GetADRMasterInfobyKeyword(adrCal.CaseNo, "CaseNo");
if (adrCase != null)
{
adrCase.ProcCode = "CAL";
adrCase.ProcDateString = cal.ProcDate.ToShortDateString();
//LGF 08012011 ADR-59: add case coordinator - add CaseCoordinatorFilter
//if (!_adrMasterList.Contains(adrCase) && CaseCoordinatorFilter(caseCoordinatorID, adrCase.CaseNo))
// _adrMasterList.Add(adrCase);
if (CaseCoordinatorFilter(caseCoordinatorID, adrCase.CaseNo))
_adrMasterList.Add(adrCase);
}
}
}
}
}
if (otherActivitiesALL != null && adrOtherActivitiesALL != null)//other activities
{
foreach (var otherActivity in otherActivitiesALL)
{
foreach (var adrotherActivity in adrOtherActivitiesALL)
{
if (otherActivity.ActivityID == adrotherActivity.ActivityID)
{
var adrCase = FileMaintenanceBusiness.Instance.GetADRMasterInfobyKeyword(adrotherActivity.CaseNo, "CaseNo");
if (adrCase != null)
{
adrCase.ProcCode = otherActivity.ProcCode;
adrCase.ProcDateString = otherActivity.ProcDate.ToShortDateString();
//LGF 08012011 ADR-59: add case coordinator - add CaseCoordinatorFilter
//if (!_adrMasterList.Contains(adrCase) && CaseCoordinatorFilter(caseCoordinatorID, adrCase.CaseNo))
if(CaseCoordinatorFilter(caseCoordinatorID, adrCase.CaseNo))
_adrMasterList.Add(adrCase);
}
}
}
}
}
}
else if (_selectedProcCode == "DSP")
{
if (dispositions != null && adrDispos != null)
{
foreach (var dispo in dispositions)
{
foreach (var adrDispo in adrDispos)
{
if (dispo.DispositionID == adrDispo.DispositionID)
{
var adrCase = FileMaintenanceBusiness.Instance.GetADRMasterInfobyKeyword(adrDispo.CaseNo, "CaseNo");
//LGF 08012011 ADR-59: add case coordinator - add CaseCoordinatorFilter
if (adrCase != null && CaseCoordinatorFilter(caseCoordinatorID, adrCase.CaseNo))
{
adrCase.ProcCode = _selectedProcCode;
//adrCase.ProcDateString = dispo.ProcDate.ToShortDateString();
_adrMasterList.Add(adrCase);
}
}
}
}
}
}
else if (_selectedProcCode == "CAL")
{
if (calendarActivities != null && adrCalActivities != null)
{
foreach (var cal in calendarActivities)
{
foreach (var adrCal in adrCalActivities)
{
if (cal.CalendarItemID == adrCal.CalendarItemID)
{
var adrCase = FileMaintenanceBusiness.Instance.GetADRMasterInfobyKeyword(adrCal.CaseNo, "CaseNo");
//LGF 08012011 ADR-59: add case coordinator - add CaseCoordinatorFilter
if (adrCase != null && CaseCoordinatorFilter(caseCoordinatorID, adrCase.CaseNo))
{
adrCase.ProcCode = _selectedProcCode;
adrCase.ProcDateString = cal.ProcDate.ToShortDateString();
_adrMasterList.Add(adrCase);
}
}
}
}
}
}
else
{
if (otherActivities != null && adrOtherActivities != null)
{
foreach (var otherActivity in otherActivities)
{
foreach (var adrotherActivity in adrOtherActivities)
{
if (otherActivity.ActivityID == adrotherActivity.ActivityID)
{
var adrCase = FileMaintenanceBusiness.Instance.GetADRMasterInfobyKeyword(adrotherActivity.CaseNo, "CaseNo");
//LGF 08012011 ADR-59: add case coordinator - add CaseCoordinatorFilter
if (adrCase != null && CaseCoordinatorFilter(caseCoordinatorID, adrCase.CaseNo))
{
adrCase.ProcCode = _selectedProcCode;
adrCase.ProcDateString = otherActivity.ProcDate.ToShortDateString();
_adrMasterList.Add(adrCase);
}
}
}
}
}
}
GeneratePrintReport();
}

That is happening because of internal identity map pattern implementation. You can never have attached two entity instances with the same entity key to the same context. You must simply call Detach once you load the entity.
context.Detach(entity);
Or you can try to load entities as non tracked (I'm not sure if it solves this problem):
context.YourEntitySet.MergeOption = MergeOption.NoTracking;
// Now run the query from YourEntitySet
Anyway it is odd that you want two instances of the same entity with different values. You should use separate non entity object for your "report" and make projections to that object. You would not have to deal with this problem at all.

Related

How to get list from docx file?

How to determine whether a list is bulleted or numbered? I use OpenXML
In general, what will be the list determines NumberingDefinitionsPart, I thought to find out the Numbering of a certain element, but this method did not work
I am processing the list in the recommended way, but I need to know which way it is
`public void ParagraphHandle(Elements.Paragraph paragraph, StringBuilder text)
{
var docPart = paragraph.DocumentPart;
var element = paragraph.Element;
var r = element.Descendants<Numbering>().ToArray();
var images = GetImages(docPart, element);
if (images.Count > 0)
{
foreach (var image in images)
{
if (image.Id != null)
{
string filePath = _saveResources.SaveImage(image);
_handler.ImageHandle(filePath, text);
}
}
return;
}
var paragraphProperties = element.GetFirstChild<ParagraphProperties>();
var numberingProperties = paragraphProperties?.GetFirstChild<NumberingProperties>();
if (numberingProperties != null)
{
var numberingId = numberingProperties.GetFirstChild<NumberingId>()?.Val?.Value;
if (numberingId != null && !paragraph.IsList)
{
text.AppendLine("<ul>");
paragraph.IsList = true;
paragraph.List = new List();
_htmlGenerator.GenerateList(paragraph, text);
}
else
{
_htmlGenerator.GenerateList(paragraph, text);
}
}
else
{
if (paragraph.IsList)
{
text.AppendLine("</ul>");
paragraph.IsList = false;
}
_handler.ParagraphHandle(element, text);
}
}`

EF Core 3.x: duplicate value

I have the following code:
public class DeviceVerizon
{
public int DeviceId { get; set; }
public string InternalDeviceId { get; set; }
}
and
public class DeviceVerizonMap : IEntityTypeConfiguration<DeviceVerizon>
{
public void Configure(EntityTypeBuilder<DeviceVerizon> builder)
{
builder.ToTable(nameof(DeviceVerizon));
builder.HasKey(d => d.DeviceId);
builder.HasIndex(v => v.InternalDeviceId).IsUnique();
builder.HasOne(o => o.Device)
.WithOne(o => o.VerizonData)
.HasForeignKey<DeviceVerizon>(a => a.DeviceId)
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
;
}
}
so, InternalDeviceId is just unique index.
some code change InternalDeviceId for existing record and add new record with the previous InternalDeviceId.
So, localDevice.VerizonData.InternalDeviceId = 1420531689
I update it for new (remoteDevice.VerizonData.InternalDeviceId = '111111111')
localDevice.VerizonData = remoteDevice.VerizonData;
_context.Devices.Update(localDevice);
then add new record with remoteDevice.VerizonData.InternalDeviceId = 1420531689:
_context.Devices.Add(remoteDevice);
and after it I call:
await _context.SaveChangesAsync();
but I get an exception:
Cannot insert duplicate key row in object 'dbo.DeviceVerizon' with
unique index 'IX_DeviceVerizon_InternalDeviceId'. The duplicate key
value is (1420531689).
The full code:
foreach (var remoteDevice in remoteVerizonDevices)
{
var localDevice = allLocalDevicesWithIMEI.Where(a =>
(string.IsNullOrWhiteSpace(remoteDevice.IMEI)
&& a.VerizonData != null
&& a.VerizonData.InternalDeviceId == remoteDevice.VerizonData.InternalDeviceId
&& a.IMSI == remoteDevice.IMSI && a.ICCID == remoteDevice.ICCID)
|| a.IMEI == remoteDevice.IMEI).FirstOrDefault();
if (localDevice != null) // device with such imei already exists or IMEI is empty on Verizon, but InternalDeviceId is the same and ICCID with IMSI are the same
{
var verizonStatus = remoteDevice.VerizonData.State.ConvertToDeviceStatusFromVerizonStatus();
var existingRequest = _context.VerizonRequests.Where(a => a.DeviceId == localDevice.Id && a.Result == VerizonRequestResult.Pending).FirstOrDefault();
if (verizonStatus == DeviceStatus.Active && remoteDevice.IsVerizonLastActiveMoreThanDays(60))
{
// existing request for this device does not exist, create new
if (existingRequest == null)
{
localDevice.Status = DeviceStatus.PendingSuspend;
localDevice.DateStatusChanging = DateTime.UtcNow;
localDevice.LastStatusChangeSource = DeviceStatusChangeSource.Verizon;
// create verizon request to change status, because device is offline more than 60 days
verizonSuspensionList.Add(localDevice.Id);
}
}
else
{
// Is Verizon status of device is different than locally?
if (localDevice.Status != verizonStatus)
{
// check whether we have active verizon request, if not, then
if (existingRequest == null)
{
// device is suspended on suremdm, we should suspend on Verizon
if (localDevice.Status == DeviceStatus.Suspended
&& verizonStatus == DeviceStatus.Active)
{
if (localDevice.Tablet != null && localDevice.Tablet.TabletGroup.GroupName == SpecialSureMdmGroups.Suspended)
verizonSuspensionList.Add(localDevice.Id);
}
else if (localDevice.Status != DeviceStatus.Suspended && verizonStatus == DeviceStatus.Suspended)
{
// if device is suspended on verizon, we need to suspend on SureMdm
localDevice.Status = DeviceStatus.PendingSuspend;
localDevice.DateStatusChanging = DateTime.UtcNow;
localDevice.LastStatusChangeSource = DeviceStatusChangeSource.Verizon;
if (localDevice.Tablet != null)
{
localDevice.Tablet.SuspensionDate = DateTime.UtcNow;
sureMdmSuspensionList.Add(new Core.Dto.DeviceManagement.SureMdm.SureMdmMoveDeviceToSuspendedGroupDto
{
TabletId = localDevice.Tablet.TabletId,
CurrentGroupId = localDevice.Tablet.TabletGroupId
});
}
}
else
{
// other cases that device on verizon has different status, that locally
VerizonStatusIsDifferentEvent?.Invoke(
remoteDevice: remoteDevice,
verizonStatus: remoteDevice.VerizonData.State.ConvertToDeviceStatusFromVerizonStatus(),
localStatus: localDevice.Status);
}
}
}
}
var changes = DeviceIsChanged(remoteDevice, localDevice);
if (changes != null && changes.Count > 0)
modifiedDevices.Add((localDevice, changes));
var continueToUpdate = true;
// if verizon data does not exist, add it
if (localDevice.VerizonData == null)
{
var existingInternalVerizonDeviceIdRecord = allDeviceVerizons.Where(a => a.InternalDeviceId == remoteDevice.VerizonData.InternalDeviceId).FirstOrDefault();
if (existingInternalVerizonDeviceIdRecord != null)
{
DeviceWithTheSameVerizonDeviceIdAlreadyExistsEvent?.Invoke(remoteDevice: remoteDevice,
localDevice: existingInternalVerizonDeviceIdRecord.Device,
verizonDeviceId: remoteDevice.VerizonData.InternalDeviceId);
continueToUpdate = false;
}
}
if (continueToUpdate)
{
localDevice.VerizonData = remoteDevice.VerizonData;
if (!string.IsNullOrWhiteSpace(remoteDevice.ICCID))
localDevice.ICCID = remoteDevice.ICCID;
localDevice.EID = remoteDevice.EID;
localDevice.ESN = remoteDevice.ESN;
if (!string.IsNullOrWhiteSpace(remoteDevice.IMSI))
localDevice.IMSI = remoteDevice.IMSI;
if (!string.IsNullOrWhiteSpace(remoteDevice.MDN))
localDevice.MDN = remoteDevice.MDN;
localDevice.MEID = remoteDevice.MEID;
localDevice.MIN = remoteDevice.MIN;
localDevice.MSISDN = remoteDevice.MSISDN;
localDevice.SKU = remoteDevice.SKU;
localDevice.SyncVerizon = true;
if (string.IsNullOrWhiteSpace(localDevice.Name))
localDevice.Name = localDevice.IMEI;
if (!localDevice.DeviceModelId.HasValue)
{
var verizonGroup = allVerizonGroups.Where(a => a.VerizonGroupName == remoteDevice.VerizonData.GroupName).FirstOrDefault();
if (!verizonGroup.DeviceModelId.HasValue)
VerizonGroupIsNotLinkedWithDeviceModelEvent?.Invoke(remoteDevice);
else
localDevice.DeviceModelId = verizonGroup.DeviceModelId;
}
_context.Devices.Update(localDevice);
}
}
else
{
// validate by Internal Verizon DeviceId
var existingInternalVerizonDeviceIdRecord = allDeviceVerizons.Where(a => a.InternalDeviceId == remoteDevice.VerizonData.InternalDeviceId).FirstOrDefault();
if (existingInternalVerizonDeviceIdRecord != null)
{
DeviceWithTheSameVerizonDeviceIdAlreadyExistsEvent?.Invoke(remoteDevice: remoteDevice,
localDevice: existingInternalVerizonDeviceIdRecord.Device,
verizonDeviceId: remoteDevice.VerizonData.InternalDeviceId);
}
else
{
// add new record
if (!string.IsNullOrWhiteSpace(remoteDevice.IMEI))
remoteDevice.Name = remoteDevice.IMEI;
else if (!string.IsNullOrWhiteSpace(remoteDevice.VerizonData.PrimaryPlaceOfUseFirstName) || !string.IsNullOrWhiteSpace(remoteDevice.VerizonData.PrimaryPlaceOfUseLastName))
remoteDevice.Name = $"{remoteDevice.VerizonData.PrimaryPlaceOfUseFirstName} {remoteDevice.VerizonData.PrimaryPlaceOfUseLastName}";
else
remoteDevice.Name = Core.Constants.Common.Undefined;
// set device Model
var verizonGroup = allVerizonGroups.Where(a => a.VerizonGroupName == remoteDevice.VerizonData.GroupName).FirstOrDefault();
if (!verizonGroup.DeviceModelId.HasValue)
VerizonGroupIsNotLinkedWithDeviceModelEvent?.Invoke(remoteDevice);
else
remoteDevice.DeviceModelId = verizonGroup.DeviceModelId;
// set device status
remoteDevice.Status = remoteDevice.VerizonData.State.ConvertToDeviceStatusFromVerizonStatus();
if (!string.IsNullOrWhiteSpace(remoteDevice.VerizonData.CarrierName))
{
var verizonCarrier = allVerizonCarriers.Where(a => a.VerizonCarrierName == remoteDevice.VerizonData.CarrierName).FirstOrDefault();
if (verizonCarrier.CarrierId.HasValue)
remoteDevice.CarrierId = verizonCarrier.CarrierId;
else
{
// notify that carrier is not found locally
LocalCarrierIsNotFoundForNewDeviceEvent?.Invoke(remoteDevice);
}
}
remoteDevice.SyncVerizon = true;
_context.Devices.Add(remoteDevice);
newDevices.Add(remoteDevice);
}
}
}
await _context.SaveChangesAsync();
why so? only one record has 1420531689, old was updated for new value (111111111) and it saved in the one transaction... How to do it correctly?

telerik mvc Create CompositeFilterDescriptor and append it to existing datasource request filter

I am having some issues creating a CompositeFilterDescriptor from scratch.
The scenario: We have date filters on the grid, but are showing date time fields.
When Someone filters to a specific date, we show all records for that day.
when someone filters greater than that day, we edit the filterDescriptor for that filter and add one day to it.
when someone filters to less than or equal to that day, we edit the filterdescriptor for that filter and add one day to it.
Here is the problem: when someone selects "not equal to", the solution would be to create a compositeFilterDescriptor containing two filters. One for less than that day, one for greater than that day.
I may ore may not be doing this part properly. I can not figure out how to add the new compositeFilterDescriptor to the existing dataSourceRequest.
Here is what I have:
static public DataSourceRequest FixDateFilters(DataSourceRequest request, string[] optionalFields = null)
{
if (request?.Filters != null)
{
List<string> matchingFields = new List<string> { "utc", "time" };
List<FilterDescriptor> newDescriptors = new List<FilterDescriptor>();
//if any fields specific to a page have been passed in, append them to the list.
if (optionalFields != null)
{
foreach (string field in optionalFields)
matchingFields.Append(field);
}
foreach (string matchingField in matchingFields)
{
List<FilterDescriptor> descriptors = new List<FilterDescriptor>();
FilterDescriptor descriptor1 = FindFirstFilterByMember(request.Filters, matchingField, true, null);
//there could be up to two filters on a matching field. Get the 2nd one if it exists.
FilterDescriptor descriptor2 = FindFirstFilterByMember(request.Filters, matchingField, true, descriptor1);
//turn the matches into a list for iterating
if (descriptor1 != null)
descriptors.Add(descriptor1);
if (descriptor2 != null)
descriptors.Add(descriptor2);
if (descriptors.Count != 0)
{
foreach (FilterDescriptor descriptor in descriptors)
{
DateTime? utcDate = (DateTime?)descriptor?.Value;
if (utcDate.HasValue)
{
utcDate = Core.DateHelper.ToUTC(utcDate.Value, HttpContext.Current); //make sure date ranges are one day ranges in local time
}
if (utcDate != null)
{
if (descriptor.Operator == FilterOperator.IsLessThanOrEqualTo)
{
utcDate = ((DateTime)utcDate).AddDays(1);
descriptor.Value = utcDate;
}
else if (descriptor.Operator == FilterOperator.IsGreaterThan)
{
utcDate = utcDate.Value.AddDays(1);
descriptor.Value = utcDate;
}
else if (descriptor.Operator == FilterOperator.IsEqualTo)
{
descriptor.Operator = FilterOperator.IsGreaterThanOrEqualTo;
newDescriptors.Add(new FilterDescriptor(descriptor.Member, FilterOperator.IsLessThan, utcDate.Value.AddDays(1)));
}
else if (descriptor.Operator == FilterOperator.IsNotEqualTo)
{
CompositeFilterDescriptor cfd = new CompositeFilterDescriptor();
cfd.LogicalOperator = FilterCompositionLogicalOperator.Or;
cfd.FilterDescriptors.Add(new FilterDescriptor(descriptor.Member, FilterOperator.IsLessThan, utcDate.Value;));
cfd.FilterDescriptors.Add(new FilterDescriptor(descriptor.Member, FilterOperator.IsGreaterThan, utcDate.Value.AddDays(1)));
newDescriptors.Add( cfd);
}
}
}
}
}
//equals matches add a new descriptor so add them after the foreach is done so they don't affect the foreach.
foreach (FilterDescriptor newDescriptor in newDescriptors)
{
if (newDescriptor.Member != "") //a blank descriptor has a emptry string for member
{
request.Filters.Add(newDescriptor);
}
}
}
return request;
}
}
static public FilterDescriptor FindFirstFilterByMember(IEnumerable<IFilterDescriptor> filters, string findMember, bool partialMatch = false, FilterDescriptor previous = null)
{
FilterDescriptor ret = null;
foreach (var filter in filters)
{
var descriptor = filter as FilterDescriptor;
if (descriptor != null
&& (descriptor.Member == findMember || (partialMatch == true && descriptor.Member.ToLower().Contains(findMember.ToLower())))
&& (previous == null || previous != descriptor))
{
ret = descriptor;
break;
}
else if (filter is CompositeFilterDescriptor)
{
ret = FindFirstFilterByMember(((CompositeFilterDescriptor)filter).FilterDescriptors, findMember, partialMatch, previous);
if (ret != null)
break;
}
}
return ret;
}
The second function is a recursive one for getting the filters by string.
The problem section is the "isNotEqualTo" comparison. I don't know how to save the composite filter into the existing request. It gives me a casting error.
Ok it turns out all i needed to do was create a new list of CompositeFilterDescriptor type and append that when necessary. The .add function took both. Sigh.
foreach (CompositeFilterDescriptor newCompositeDescriptor in newCompositeDescriptors)
{
request.Filters.Add(newCompositeDescriptor);
}

I am getting multiple headers and footers in word document, getting null in policy.GetFirstPageHeader() using NPOI

I am getting multiple headers and footers in a Word document; I cannot differentiate the firstpage, default(odd), or even headers.
When I am trying to call policy.GetFirstPageHeader() I am getting a null value.
XWPFHeaderFooterPolicy policy = new XWPFHeaderFooterPolicy(document);
var headerList = document.HeaderList;
var footerList = document.FooterList;
var firstPageHeader = policy.GetFirstPageHeader();
var firstPageFooter = policy.GetFirstPageFooter();
XWPFHeader header = policy.GetDefaultHeader();
XWPFHeader even = policy.GetEvenPageHeader();
XWPFHeader odd = policy.GetOddPageHeader();
I am getting null values. Can any one suggest how to differentiate headers in a Word document?
var listOfheaders = new List<CT_HdrFtrRef>();
foreach (var par in document.Paragraphs)
{
var ParagraphsectPr = (CT_P)par.GetType().GetField("paragraph", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(par);
if (ParagraphsectPr.pPr.sectPr != null)
{
foreach (var headerref in ParagraphsectPr.pPr.sectPr.headerReference)
{
listOfheaders.Add(headerref);
}
}
}
foreach (var list in listOfheaders)
{
var relatedPart = document.GetRelationById(list.id);
XWPFHeader hdr = null;
if (relatedPart != null && relatedPart is XWPFHeader)
{
hdr = (XWPFHeader)relatedPart;
}
// Assign it
ST_HdrFtr type = list.type;
if (!string.IsNullOrEmpty(hdr.Text))
{
if (type == ST_HdrFtr.first)
{
firstPageHeadr = hdr;
}
else if (type == ST_HdrFtr.even)
{
evenPageHeader = hdr;
}
else
{
defaultHeader = hdr;
}
}
}

Only Update Entity (Parent or children) if Property Values Have Changed with EF

As I build a project with Entity Framework 6 (using EF for the first time), I noticed that when I only Update the relationships of an Entity, EF updates the main Entity too.
I can tell this is happening because I'm using System Versioned tables on Sql Server 2017.
This is a made up scenario, but most of the concept is here.
public async Task<ActionResult> Edit([Bind(Include="Id,Name,LocationTimes")] LocationViewModel locationVM) {
if (ModelState.IsValid) {
var location = await _db.Locations.FirstOrDefaultAsync(l => l.Id == locationsViewModel.Id && l.UserId == UserId);
if (location == null) {
return HttpNotFound();
}
location.Name = locationsViewModel.Name;
// ... other properties
foreach (var day in locationsViewModel.LocationTimes.Days) {
var time = new Time {
Day = day.Day,
OpenTime = day.OpenTime,
CloseTime = day.CloseTime,
};
// Find current Time or keep newly created
time = await time.FindByTimeAsync(time, _db) ?? time;
// Find LocationTime with same day
var locationTime = location.LocationTimes.FirstOrDefault(lt => lt.Time.Day == day.Day);
// If all times are the same, skip (continue)
if (locationTime != null && locationTime.Time.OpenTime == time.OpenTime && locationTime.Time.CloseTime == time.CloseTime)
continue;
if (locationTime != null && (locationTime.Time.OpenTime != time.OpenTime || locationTime.Time.CloseTime != time.CloseTime)) {
// Remove, At least one of the Times do not match
locationTime.Time = time;
_db.Entry(locationTime).State = EntityState.Modified;
} else {
location.LocationTimes.Add(new LocationTime {
Location = location,
Time = time,
});
}
}
_db.Entry(location).State = EntityState.Modified;
await _db.SaveChangesAsync();
return RedirectToAction("Index");
}
}
I assume, that by marking the entire Entity as Modified, EF will call the update statement.
How can I avoid an UPDATE to the parent Entity, if no properties have changed on the parent, but still Add/Update the child relationships?
I assume I have to check that each property has not changed and therefore I should not be setting location state to Modified, but how would I handle the newly added Times?
Update #1
So I tried what I mentioned and it works, but is this the correct way to do this?
public async Task<ActionResult> Edit([Bind(Include="Id,Name,LocationTimes")] LocationViewModel locationVM) {
if (ModelState.IsValid) {
var location = await _db.Locations.FirstOrDefaultAsync(l => l.Id == locationsViewModel.Id && l.UserId == UserId);
if (location == null) {
return HttpNotFound();
}
/*******************
This is new part
*******************/
if (
location.Name != locationsViewModel.Name
// || ... test other properties
) {
location.Name = locationsViewModel.Name;
// ... other properties
_db.Entry(location).State = EntityState.Modified;
} else {
_db.Entry(location).State = EntityState.Unchanged;
}
/*******************/
foreach (var day in locationsViewModel.LocationTimes.Days) {
var time = new Time {
Day = day.Day,
OpenTime = day.OpenTime,
CloseTime = day.CloseTime,
};
// Find current Time or keep newly created
time = await time.FindByTimeAsync(time, _db) ?? time;
// Find LocationTime with same day
var locationTime = location.LocationTimes.FirstOrDefault(lt => lt.Time.Day == day.Day);
// If all times are the same, skip (continue)
if (locationTime != null && locationTime.Time.OpenTime == time.OpenTime && locationTime.Time.CloseTime == time.CloseTime)
continue;
if (locationTime != null && (locationTime.Time.OpenTime != time.OpenTime || locationTime.Time.CloseTime != time.CloseTime)) {
// Remove, At least one of the Times do not match
locationTime.Time = time;
_db.Entry(locationTime).State = EntityState.Modified;
} else {
location.LocationTimes.Add(new LocationTime {
Location = location,
Time = time,
});
}
}
/* removed, added above */
//_db.Entry(location).State = EntityState.Modified;
await _db.SaveChangesAsync();
return RedirectToAction("Index");
}
}
So after trial and error, I guess I misunderstood how EF handles the EntityState. I though if a child was Modified, you had to set the parent as Modified as well.
Gladly, that's not the case and the code below works as desired.
public async Task<ActionResult> Edit([Bind(Include="Id,Name,LocationTimes")] LocationViewModel locationVM) {
if (ModelState.IsValid) {
var location = await _db.Locations.FirstOrDefaultAsync(l => l.Id == locationsViewModel.Id && l.UserId == UserId);
if (location == null) {
return HttpNotFound();
}
/*******************
This is new part
check if at least one property was changed
*******************/
if (
location.Name != locationsViewModel.Name
|| location.Ref != locationsViewModel.Ref
// || ... test other properties
) {
location.Name = locationsViewModel.Name;
location.Ref = locationsViewModel.Ref;
// ... other properties
// Tell EF that the Entity has been modified (probably not needed, but just in case)
_db.Entry(location).State = EntityState.Modified;
} else {
// Tell EF that the Entity has *NOT* been modified
_db.Entry(location).State = EntityState.Unchanged;
}
/*******************/
foreach (var day in locationsViewModel.LocationTimes.Days) {
var time = new Time {
Day = day.Day,
OpenTime = day.OpenTime,
CloseTime = day.CloseTime,
};
// Find current Time or keep newly created
time = await time.FindByTimeAsync(time, _db) ?? time;
// Find LocationTime with same day
var locationTime = location.LocationTimes.FirstOrDefault(lt => lt.Time.Day == day.Day);
// If all times are the same, skip (continue)
if (locationTime != null && locationTime.Time.OpenTime == time.OpenTime && locationTime.Time.CloseTime == time.CloseTime)
continue;
if (locationTime != null && (locationTime.Time.OpenTime != time.OpenTime || locationTime.Time.CloseTime != time.CloseTime)) {
// Remove, At least one of the Times do not match
locationTime.Time = time;
_db.Entry(locationTime).State = EntityState.Modified;
} else {
location.LocationTimes.Add(new LocationTime {
Location = location,
Time = time,
});
}
}
/* removed, added above */
//_db.Entry(location).State = EntityState.Modified;
await _db.SaveChangesAsync();
return RedirectToAction("Index");
}
}