I have the following code:
public void SetUser(User user)
{
string streetNumber = "";
if (user.Address.StreetNo != null)
streetNumber = user.Address.StreetNo.ToString();
else
streetNumber = "";
}
I get the ever popular
Object reference not set to an instance of an object.
issue.
public void SetUser(User user)
{
string streetNumber = "";
if (user != null && user.Address != null && user.Address.StreetNo != null) {
streetNumber = user.Address.StreetNo.ToString();
}
}
Taking into account #CKoenig's suggestion, the following throws an exception if the user or user.Address are null:
public void SetUser(User user)
{
if (user == null) {
throw new System.ArgumentNullException("user", "user cannot be null");
}
if (user.Address == null) {
throw new System.ArgumentNullException("Address", "Address cannot be null");
}
string streetNumber = "";
if (user.Address.StreetNo != null) {
streetNumber = user.Address.StreetNo.ToString();
}
}
public void SetUser(User user)
{
string streetNumber = String.Empty;
if (user!= null
&& user.Address != null
&& user.Address.StreetNo != null)
{
streetNumber = user.Address.StreetNo.ToString();
}
}
Either user is null, or user.Address is null. You need to test them too.
Check your stacktrace and:
user
user.Address
user.Address.StreetNo
with an if ... == null then ...
if (user != null
&& user.Address != null
&& user.Address.StreetNo != null)
{
// ...
}
Related
I´m writing an API in .net/C# and have a problem with the following service function:
public async Task<List<Item>> GetAsync(RequestParameters requestParameters) =>
await _itemsCollection.Find(item => (item.item_description.Contains(requestParameters.FilterDescString) ||
item.item_adddesc.Contains(requestParameters.FilterDescString)) &&
item.item_id.Equals(requestParameters.FilterItemIdInt) &&
item.item_amount.Equals(requestParameters.FilterAmountInt) &&
item.item_width.Equals(requestParameters.FilterWidthInt) &&
item.item_height.Equals(requestParameters.FilterHeightInt) &&
item.item_weight.Equals(requestParameters.FilterWeightInt) &&
item.item_aunumber.Contains(requestParameters.FilterAunumberString))
.SortByDescending(i => i.item_id).Skip((requestParameters.PageNumber)* requestParameters.PageSize).Limit(requestParameters.PageSize)
.ToListAsync();
Here are non-null-values neccessary for all filters, but null values should be ignored in query. How can I achieve that? Regards
Edit:
If I have no value for any of that integers I need kind of a wildcard. Here is my model:
public class RequestParameters
{
const int MaxPageSize = 50;
public int PageNumber { get; set; } = 1;
private int _pageSize = 25;
private string _filterDescString = "";
private string _filterAunumberString = "";
private int? _filterItemIdInt = null;
private int? _filterAmountInt = null;
private int? _filterWidthInt = null;
private int? _filterHeightInt = null;
private int? _filterWeightInt = null;
public int PageSize
{
get
{
return _pageSize;
}
set
{
_pageSize = (value > MaxPageSize) ? MaxPageSize : value;
}
}
public string FilterDescString
{
get
{
return _filterDescString;
}
set
{
_filterDescString = (value != null) ? value : _filterDescString;
}
}
public string FilterAunumberString
{
get
{
return _filterAunumberString;
}
set
{
_filterAunumberString = (value != null) ? value : _filterAunumberString;
}
}
public int? FilterItemIdInt
{
get
{
return _filterItemIdInt;
}
set
{
_filterItemIdInt = (value != null) ? value : _filterItemIdInt;
}
}
public int? FilterAmountInt
{
get
{
return _filterAmountInt;
}
set
{
_filterAmountInt = (value != null) ? value : _filterAmountInt;
}
}
public int? FilterWidthInt
{
get
{
return _filterWidthInt;
}
set
{
_filterWidthInt = (value != null) ? value : _filterWidthInt;
}
}
public int? FilterHeightInt
{
get
{
return _filterHeightInt;
}
set
{
_filterHeightInt = (value != null) ? value : _filterHeightInt;
}
}
public int? FilterWeightInt
{
get
{
return _filterWeightInt;
}
set
{
_filterWeightInt = (value != null) ? value : _filterWeightInt;
}
}
}
The initial call looks like this, the user can add various combinations of that string and int filters:
https://localhost:7010/api/Items?PageNumber=0&PageSize=25&FilterDescString=&FilterAunumberString=&FilterAmountInt=null&FilterWidthInt=null&FilterHeightInt=null&FilterWeightInt=null&FilterItemIdInt=null
The initial call and all calls that have at least a value for all of the integers return an empty array.
I proceeded with a solution that uses FilterDefinitions on the mongodb thats connected with my API. Filtering for STRINGS works fine, but on filtering INT I get an empty array. Here is my solution:
public static FilterDefinition<Item> ParamsToFilter(RequestParameters requestParameters)
{
var builder = Builders<Item>.Filter;
var filter = builder.Empty;
if (!string.IsNullOrWhiteSpace(requestParameters.FilterDescString))
{
var descFilter = builder.Regex(i => i.item_description, requestParameters.FilterDescString);
filter &= descFilter;
}
if (!string.IsNullOrWhiteSpace(requestParameters.FilterAddDescString))
{
var addDescFilter = builder.Regex(i => i.item_adddesc, requestParameters.FilterAddDescString);
filter &= addDescFilter;
}
if (!string.IsNullOrWhiteSpace(requestParameters.FilterAunumberString))
{
var aunumberFilter = builder.Regex(i => i.item_aunumber, requestParameters.FilterAunumberString);
filter &= aunumberFilter;
}
if (requestParameters.FilterItemIdInt != null)
{
var itemIdFilter = builder.Eq(i => i.item_id, requestParameters.FilterItemIdInt);
filter &= itemIdFilter;
}
if (requestParameters.FilterAmountInt != null)
{
var itemAmountFilter = builder.Eq(i => i.item_amount, requestParameters.FilterAmountInt);
filter &= itemAmountFilter;
}
if (requestParameters.FilterWidthInt != null)
{
var itemWidthFilter = builder.Eq(i => i.item_width, requestParameters.FilterWidthInt);
filter &= itemWidthFilter;
}
if (requestParameters.FilterHeightInt != null)
{
var itemHeightFilter = builder.Eq(i => i.item_height, requestParameters.FilterHeightInt);
filter &= itemHeightFilter;
}
if (requestParameters.FilterWeightInt != null)
{
var itemWeightFilter = builder.Eq(i => i.item_weight, requestParameters.FilterWeightInt);
filter &= itemWeightFilter;
}
return filter;
}
This is a static method that just adds a filter to the FilterDefinition if there a non-null or non-empty filtervalue for the specific column in the db.
public async Task<List<Item>> GetAsync(RequestParameters requestParameters)
{
var filters = ParamsToFilter(requestParameters);
return await _itemsCollection.Find(filters).SortByDescending(i => i.item_id).Skip((requestParameters.PageNumber) * requestParameters.PageSize).Limit(requestParameters.PageSize).ToListAsync();
}
Later I use the given filters in the GetAsync() method with Find(). Regards
I have simple application which saves programmatically folders and emails in local Outlook application. Code works fine but I observed that I have to add sleep when folder or message has been created otherwise some folders and messages are randomly missing.
This is my code:
public class EmailBoxToOutlookAppExporter : IEmailBoxExporter
{
private IList<EmaillBox> _emailBoxes;
private Application _outlookApplication;
private NameSpace _nameSpace;
private bool _killOutlookProcesWhenFinished;
private string PR_MESSAGE_DELIVERY_TIME = "http://schemas.microsoft.com/mapi/proptag/0x0E060040";
private string _exchangeUserName;
private string _imapUserName;
public EmailBoxToOutlookAppExporter(IList<EmaillBox> emailBoxes, string exchangeUserName, string imapUserName)
{
_emailBoxes = emailBoxes;
_exchangeUserName = exchangeUserName;
_imapUserName = imapUserName;
}
public void Export()
{
_outlookApplication = getOutlookApplication();
_nameSpace = _outlookApplication.GetNamespace("MAPI");
if(_emailBoxes != null && _emailBoxes.Count > 0)
{
int nbOfMessagesToProcess = _emailBoxes.Sum(e => e.EmailMessages.Count);
int nbOfMessagesProcessed = 0;
foreach(EmaillBox emailBox in _emailBoxes)
{
MAPIFolder folderInfo = createMailBoxFolder(emailBox);
waitForOutlookItem();
if (emailBox.EmailMessages != null && emailBox.EmailMessages.Count > 0)
{
foreach (EmailMessage emailMessage in emailBox.EmailMessages)
{
createEmailMessage(emailMessage, folderInfo);
waitForOutlookItem();
createContacts(emailMessage);
waitForOutlookItem();
nbOfMessagesProcessed++;
ProcessProgress.SetProgress(KnownProcessName.ExportEmailBoxesToLocalOutlookApp, nbOfMessagesProcessed, nbOfMessagesToProcess);
}
}
else
{
//add logging...
}
//Marshal.ReleaseComObject(folderInfo);
}
}
else
{
ProcessProgress.SetProgress(KnownProcessName.ExportEmailBoxesToLocalOutlookApp, 0, 0);
}
if (_killOutlookProcesWhenFinished)
{
killOutlookApplicationProcess();
startOutlookApplicationProcess();
}
}
private MAPIFolder createMailBoxFolder(EmaillBox emailBox)
{
MAPIFolder mapiFolder = findMailBoxRootFolder();
IList<string> splittedEmailBoxPath = emailBox.Name.Split('/');
foreach (string emailBoxPathPart in splittedEmailBoxPath)
{
MAPIFolder nextMapiFolder = findSubFolder(mapiFolder, emailBoxPathPart);
if (nextMapiFolder == null)
{
mapiFolder = addNewSubFolder(mapiFolder, emailBoxPathPart);
}
else
mapiFolder = nextMapiFolder;
}
return mapiFolder;
}
private MAPIFolder findMailBoxRootFolder()
{
Store selectedStore = null;
foreach(Store store in _nameSpace.Session.Stores)
{
if(store.DisplayName.ToUpper() == _exchangeUserName.ToUpper())
{
selectedStore = store;
}
}
if (selectedStore == null)
selectedStore = _nameSpace.Session.DefaultStore;
MAPIFolder rootFolder = selectedStore.GetRootFolder();
MAPIFolder imapUserNameFolder = findSubFolder(rootFolder, _imapUserName);
if (imapUserNameFolder == null)
{
rootFolder = addNewSubFolder(rootFolder, _imapUserName);
waitForOutlookItem();
}
else
rootFolder = imapUserNameFolder;
return rootFolder;
}
private MAPIFolder findSubFolder(MAPIFolder parentFolderId, string folderName)
{
MAPIFolder mAPIFolder = null;
foreach (MAPIFolder subFolder in parentFolderId.Folders)
{
if(subFolder.Name.ToUpper() == folderName.ToUpper())
{
mAPIFolder = subFolder;
break;
}
}
return mAPIFolder;
}
private MAPIFolder addNewSubFolder(MAPIFolder parentMapiFolder, string folderName)
{
MAPIFolder newFolder = parentMapiFolder.Folders.Add(folderName);
return newFolder;
}
private MailItem createEmailMessage(EmailMessage emailMessage, MAPIFolder mapiFolder)
{
MailItem mailItem = null;
if(emailMessage != null && mapiFolder != null)
{
mailItem = (MailItem)_outlookApplication.CreateItem(OlItemType.olMailItem);
mailItem.UnRead = false;
mailItem.Subject = emailMessage.Subject;
mailItem.Body = emailMessage.Body;
mailItem.To = getPeoplesList(emailMessage.To);
mailItem.CC = getPeoplesList(emailMessage.Cc);
mailItem.BCC = getPeoplesList(emailMessage.Bcc);
mailItem.SentOnBehalfOfName = emailMessage.From?.EmailAddress;
PropertyAccessor propertyAccessor = mailItem.PropertyAccessor;
propertyAccessor.SetProperty(PR_MESSAGE_DELIVERY_TIME, emailMessage.Date);
if (emailMessage.Attachments != null && emailMessage.Attachments.Count > 0)
{
foreach (Model.Attachment attachment in emailMessage.Attachments)
createAttachment(attachment, mailItem);
}
mailItem.Move(mapiFolder);
}
return mailItem;
}
private void createContacts(EmailMessage emailMessage)
{
createContact(emailMessage.From);
foreach (Person person in emailMessage.To)
createContact(person);
foreach (Person person in emailMessage.Cc)
createContact(person);
foreach (Person person in emailMessage.Bcc)
createContact(person);
}
private ContactItem createContact(Person person)
{
ContactItem contactItem = null;
if(person != null)
{
MAPIFolder contactsFolder = _outlookApplication.Session.GetDefaultFolder(OlDefaultFolders.olFolderContacts);
if(contactsFolder != null && contactsFolder.Items != null && contactsFolder.Items.Count > 0)
{
foreach (ContactItem existingContactItem in contactsFolder.Items)
{
if (existingContactItem.Email1Address == person.EmailAddress)
{
contactItem = existingContactItem;
break;
}
}
}
if (contactItem == null)
{
contactItem = _outlookApplication.CreateItem(OlItemType.olContactItem) as ContactItem;
contactItem.Email1Address = person.EmailAddress;
contactItem.FullName = person.DisplayName;
contactItem.Save();
}
}
return contactItem;
}
private string getPeoplesList(IList<Person> peoples)
{
string peoplesList = string.Empty;
if (peoples != null && peoples.Count > 0)
peoplesList = string.Join(";", peoples.Select(p => p.EmailAddress));
return peoplesList;
}
private void createAttachment(Model.Attachment attachment, MailItem mailItem)
{
if(attachment != null && mailItem != null)
{
string filePath = Path.Combine(ApplicationSettings.RootFolder, attachment.FileName);
byte[] attachmentBytes;
if (attachment.ContentTransferEncoding != null)
attachmentBytes = Convert.FromBase64String(attachment.Content);
else
attachmentBytes = attachment.Encoding.GetBytes(attachment.Content);
File.WriteAllBytes(filePath, attachmentBytes);
mailItem.Attachments.Add(filePath);
File.Delete(filePath);
}
}
private Application getOutlookApplication()
{
Application outlookApplication = null;
try
{
outlookApplication = Marshal.GetActiveObject("Outlook.Application") as Application;
}
catch
{
//add logging...
}
if (outlookApplication == null)
{
outlookApplication = new Application();
_killOutlookProcesWhenFinished = true;
}
return outlookApplication;
}
private void killOutlookApplicationProcess()
{
Process outlookApplicationProcess = Process.GetProcesses().
FirstOrDefault(pr => pr.ProcessName.ToUpper() == "OUTLOOK");
if(outlookApplicationProcess != null)
{
outlookApplicationProcess.Kill();
}
}
private void startOutlookApplicationProcess()
{
Process.Start("OUTLOOK");
}
private void waitForOutlookItem()
{
System.Threading.Thread.Sleep(700);
}
}
So my question is: how to deal with waitForOutlookItem() method and make this code work without hardcoded sleep?
Thank you in advance!
I've built a program that creates employee schedules and assigns employees to those schedules. I can assign the schedule with no issues, but I'm having problems figuring out how to make that schedule disappear from the dropdown list if it's already been assigned to an employee so that the same schedule isn't given to two employees.
#Html.DropDownListFor(m => m.ApplicationUser.ScheduleSum, new SelectList(Model.ScheduleBuilderList, "ScheduleSummary", "ScheduleSummary"), "Choose a schedule", new {#class = "form-control"}
How can I get a schedule ID to disappear when assigned and reappeared if not assigned?
Let me know if you need any additional information.
Schedule Model
public int Id { get; set; }
public int ScheduleId { get; set; }
public string DaysMatching { get; set; }
public string Days { get; set; }
public string ScheduleSummary { get; set; }
public string MondaySchedule { get; set; }
public string TuesdaySchedule { get; set; }
public string WednesdaySchedule { get; set; }
public string ThursdaySchedule { get; set; }
public string FridaySchedule { get; set; }
public string SaturdaySchedule { get; set; }
public string SundaySchedule { get; set; }
public string MondayStartTime { get; set; }
public string TuesdayStartTime { get; set; }
public string WednesdayStartTime { get; set; }
public string ThursdayStartTime { get; set; }
public string FridayStartTime { get; set; }
public string SaturdayStartTime { get; set; }
public string SundayStartTime { get; set; }
public string MondayEndTime { get; set; }
public string TuesdayEndTime { get; set; }
public string WednesdayEndTime { get; set; }
public string ThursdayEndTime { get; set; }
public string FridayEndTime { get; set; }
public string SaturdayEndTime { get; set; }
public string SundayEndTime { get; set; }
public string MondayFirstBreak { get; set; }
public string TuesdayFirstBreak { get; set; }
public string WednesdayFirstBreak { get; set; }
public string ThursdayFirstBreak { get; set; }
public string FridayFirstBreak { get; set; }
public string SaturdayFirstBreak { get; set; }
public string SundayFirstBreak { get; set; }
public string MondaySecondBreak { get; set; }
public string TuesdaySecondBreak { get; set; }
public string WednesdaySecondBreak { get; set; }
public string ThursdaySecondBreak { get; set; }
public string FridaySecondBreak { get; set; }
public string SaturdaySecondBreak { get; set; }
public string SundaySecondBreak { get; set; }
public string MondayLunch { get; set; }
public string TuesdayLunch { get; set; }
public string WednesdayLunch { get; set; }
public string ThursdayLunch { get; set; }
public string FridayLunch { get; set; }
public string SaturdayLunch { get; set; }
public string SundayLunch { get; set; }
Employee Model
public class ApplicationUser : IdentityUser
{
public int ScheduleId { get; set; }
public ScheduleBuilder ScheduleBuilder { get; set; }
public string ScheduleSum { get; set; }
[Required]
[DataType(DataType.PhoneNumber)]
[RegularExpression(#"^\(?([0-9]{3})\)?[-]([0-9]{3})[-]([0-9]{4})$", ErrorMessage = "Please enter correct format with hyphens. i.e. 407-200-2000")]
[Display(Name = "Phone Number")]
public string PhoneNumbers { get; set; }
[Required]
[Display(Name = "First Name")]
public string FirstName { get; set; }
[Required]
[Display(Name = "Last Name")]
public string LastName { get; set; }
[Required(ErrorMessage = "You must provide a valid Email")]
public string EmailAccount => Email;
}
Schedule Controller Save ActionResult
[HttpPost]
public ActionResult Save(ScheduleBuilder scheduleBuilder)
{
if (!ModelState.IsValid)
{
var viewModel = new TierViewModel()
{
ScheduleBuilder = scheduleBuilder
};
return View("ScheduleBuilder", viewModel);
}
if (scheduleBuilder.Id == 0)
{
_context.ScheduleBuilder.Add(scheduleBuilder);
if (scheduleBuilder.MondayStartTime != null)
{
scheduleBuilder.MondaySchedule = "Mon";
}
if (scheduleBuilder.TuesdayStartTime != null)
{
scheduleBuilder.TuesdaySchedule = "Tue";
}
if (scheduleBuilder.WednesdayStartTime != null)
{
scheduleBuilder.WednesdaySchedule = "Wed";
}
if (scheduleBuilder.ThursdayStartTime != null)
{
scheduleBuilder.ThursdaySchedule = "Thur";
}
if (scheduleBuilder.FridayStartTime != null)
{
scheduleBuilder.FridaySchedule = "Fri";
}
if (scheduleBuilder.SaturdayStartTime != null)
{
scheduleBuilder.SaturdaySchedule = "Sat";
}
if (scheduleBuilder.SundayStartTime != null)
{
scheduleBuilder.SundaySchedule = "Sun";
}
scheduleBuilder.Days = scheduleBuilder.SundaySchedule + " " +
scheduleBuilder.MondaySchedule + " " +
scheduleBuilder.TuesdaySchedule + " " +
scheduleBuilder.WednesdaySchedule + " " +
scheduleBuilder.ThursdaySchedule + " " +
scheduleBuilder.FridaySchedule + " " +
scheduleBuilder.SaturdaySchedule;
scheduleBuilder.DaysMatching = "Yes";
var startTime = scheduleBuilder.MondayStartTime + "-" + scheduleBuilder.MondayEndTime;
if (scheduleBuilder.MondayStartTime == null)
{
startTime = scheduleBuilder.TuesdayStartTime + "-" + scheduleBuilder.TuesdayEndTime;
}
if (scheduleBuilder.MondayStartTime == null && scheduleBuilder.TuesdayStartTime == null)
{
startTime = scheduleBuilder.WednesdayStartTime + "-" + scheduleBuilder.WednesdayEndTime;
}
if (scheduleBuilder.WednesdayStartTime == null && scheduleBuilder.MondayStartTime == null && scheduleBuilder.TuesdayStartTime == null)
{
startTime = scheduleBuilder.ThursdayStartTime + "-" + scheduleBuilder.ThursdayEndTime; ;
}
if (scheduleBuilder.ThursdayStartTime == null && scheduleBuilder.WednesdayStartTime == null && scheduleBuilder.MondayStartTime == null && scheduleBuilder.TuesdayStartTime == null)
{
startTime = scheduleBuilder.FridayStartTime + "-" + scheduleBuilder.FridayEndTime; ;
}
if (scheduleBuilder.FridayStartTime == null && scheduleBuilder.ThursdayStartTime == null && scheduleBuilder.WednesdayStartTime == null && scheduleBuilder.TuesdayStartTime == null && scheduleBuilder.MondayStartTime == null)
{
startTime = scheduleBuilder.SaturdayStartTime + "-" + scheduleBuilder.SaturdayEndTime; ;
}
if (scheduleBuilder.SaturdayStartTime == null && scheduleBuilder.FridayStartTime == null && scheduleBuilder.ThursdayStartTime == null && scheduleBuilder.WednesdayStartTime == null && scheduleBuilder.TuesdayStartTime == null && scheduleBuilder.MondayStartTime == null)
{
startTime = scheduleBuilder.SundayStartTime + "-" + scheduleBuilder.SundayEndTime; ;
}
System.Diagnostics.Debug.Write("Monday End Time: " + scheduleBuilder.MondayEndTime);
System.Diagnostics.Debug.Write("Sunday End Time: " + scheduleBuilder.SundayEndTime);
if (scheduleBuilder.SundayStartTime != scheduleBuilder.MondayStartTime && scheduleBuilder.MondayStartTime != null && scheduleBuilder.SundayStartTime != null || scheduleBuilder.SundayEndTime != scheduleBuilder.MondayEndTime && scheduleBuilder.MondayEndTime != null && scheduleBuilder.SundayEndTime != null
|| scheduleBuilder.SundayStartTime != scheduleBuilder.TuesdayStartTime && scheduleBuilder.TuesdayStartTime != null && scheduleBuilder.SundayStartTime != null || scheduleBuilder.SundayEndTime != scheduleBuilder.TuesdayEndTime && scheduleBuilder.TuesdayEndTime != null && scheduleBuilder.SundayEndTime != null
|| scheduleBuilder.SundayStartTime != scheduleBuilder.WednesdayStartTime && scheduleBuilder.WednesdayStartTime != null && scheduleBuilder.SundayStartTime != null || scheduleBuilder.SundayEndTime != scheduleBuilder.WednesdayEndTime && scheduleBuilder.WednesdayEndTime != null && scheduleBuilder.SundayEndTime != null
|| scheduleBuilder.SundayStartTime != scheduleBuilder.ThursdayStartTime && scheduleBuilder.ThursdayStartTime != null && scheduleBuilder.SundayStartTime != null || scheduleBuilder.SundayEndTime != scheduleBuilder.ThursdayEndTime && scheduleBuilder.ThursdayEndTime != null && scheduleBuilder.SundayEndTime != null
|| scheduleBuilder.SundayStartTime != scheduleBuilder.FridayStartTime && scheduleBuilder.FridayStartTime != null && scheduleBuilder.SundayStartTime != null || scheduleBuilder.SundayEndTime != scheduleBuilder.FridayEndTime && scheduleBuilder.FridayEndTime != null && scheduleBuilder.SundayEndTime != null
|| scheduleBuilder.SundayStartTime != scheduleBuilder.SaturdayStartTime && scheduleBuilder.SaturdayStartTime != null && scheduleBuilder.SundayStartTime != null || scheduleBuilder.SundayEndTime != scheduleBuilder.SaturdayEndTime && scheduleBuilder.SaturdayEndTime != null && scheduleBuilder.SundayEndTime != null
|| scheduleBuilder.MondayStartTime != scheduleBuilder.TuesdayStartTime && scheduleBuilder.TuesdayStartTime != null && scheduleBuilder.MondayStartTime != null || scheduleBuilder.MondayEndTime != scheduleBuilder.TuesdayEndTime && scheduleBuilder.MondayEndTime != null && scheduleBuilder.TuesdayEndTime != null
|| scheduleBuilder.MondayStartTime != scheduleBuilder.WednesdayStartTime && scheduleBuilder.WednesdayStartTime != null && scheduleBuilder.MondayStartTime != null || scheduleBuilder.MondayEndTime != scheduleBuilder.WednesdayEndTime && scheduleBuilder.MondayEndTime != null && scheduleBuilder.WednesdayEndTime != null
|| scheduleBuilder.MondayStartTime != scheduleBuilder.ThursdayStartTime && scheduleBuilder.ThursdayStartTime != null && scheduleBuilder.MondayStartTime != null || scheduleBuilder.MondayEndTime != scheduleBuilder.ThursdayEndTime && scheduleBuilder.MondayEndTime != null && scheduleBuilder.ThursdayEndTime != null
|| scheduleBuilder.MondayStartTime != scheduleBuilder.FridayStartTime && scheduleBuilder.FridayStartTime != null && scheduleBuilder.MondayStartTime != null || scheduleBuilder.MondayEndTime != scheduleBuilder.FridayEndTime && scheduleBuilder.MondayEndTime != null && scheduleBuilder.FridayEndTime != null
|| scheduleBuilder.MondayStartTime != scheduleBuilder.SaturdayStartTime && scheduleBuilder.SaturdayStartTime != null && scheduleBuilder.MondayStartTime != null || scheduleBuilder.MondayEndTime != scheduleBuilder.SaturdayEndTime && scheduleBuilder.MondayEndTime != null && scheduleBuilder.SaturdayEndTime != null
|| scheduleBuilder.TuesdayStartTime != scheduleBuilder.WednesdayStartTime && scheduleBuilder.WednesdayStartTime != null && scheduleBuilder.TuesdayStartTime != null || scheduleBuilder.TuesdayEndTime != scheduleBuilder.WednesdayEndTime && scheduleBuilder.WednesdayEndTime != null && scheduleBuilder.TuesdayEndTime != null
|| scheduleBuilder.TuesdayStartTime != scheduleBuilder.ThursdayStartTime && scheduleBuilder.ThursdayStartTime != null && scheduleBuilder.TuesdayStartTime != null || scheduleBuilder.TuesdayEndTime != scheduleBuilder.ThursdayEndTime && scheduleBuilder.ThursdayEndTime != null && scheduleBuilder.TuesdayEndTime != null
|| scheduleBuilder.TuesdayStartTime != scheduleBuilder.FridayStartTime && scheduleBuilder.FridayStartTime != null && scheduleBuilder.TuesdayStartTime != null || scheduleBuilder.TuesdayEndTime != scheduleBuilder.FridayEndTime && scheduleBuilder.FridayEndTime != null && scheduleBuilder.TuesdayEndTime != null
|| scheduleBuilder.TuesdayStartTime != scheduleBuilder.SaturdayStartTime && scheduleBuilder.SaturdayStartTime != null && scheduleBuilder.TuesdayStartTime != null || scheduleBuilder.TuesdayEndTime != scheduleBuilder.SaturdayEndTime && scheduleBuilder.SaturdayEndTime != null && scheduleBuilder.TuesdayEndTime != null
|| scheduleBuilder.WednesdayStartTime != scheduleBuilder.ThursdayStartTime && scheduleBuilder.ThursdayStartTime != null && scheduleBuilder.WednesdayStartTime != null || scheduleBuilder.WednesdayEndTime != scheduleBuilder.ThursdayEndTime && scheduleBuilder.ThursdayEndTime != null && scheduleBuilder.WednesdayEndTime != null
|| scheduleBuilder.WednesdayStartTime != scheduleBuilder.FridayStartTime && scheduleBuilder.FridayStartTime != null && scheduleBuilder.WednesdayStartTime != null || scheduleBuilder.WednesdayEndTime != scheduleBuilder.FridayEndTime && scheduleBuilder.FridayEndTime != null && scheduleBuilder.WednesdayEndTime != null
|| scheduleBuilder.WednesdayStartTime != scheduleBuilder.SaturdayStartTime && scheduleBuilder.SaturdayStartTime != null && scheduleBuilder.WednesdayStartTime != null || scheduleBuilder.WednesdayEndTime != scheduleBuilder.SaturdayEndTime && scheduleBuilder.SaturdayEndTime != null && scheduleBuilder.WednesdayEndTime != null
|| scheduleBuilder.ThursdayStartTime != scheduleBuilder.FridayStartTime && scheduleBuilder.ThursdayStartTime != null && scheduleBuilder.FridayStartTime != null || scheduleBuilder.ThursdayEndTime != scheduleBuilder.FridayEndTime && scheduleBuilder.ThursdayEndTime != null && scheduleBuilder.FridayEndTime != null
|| scheduleBuilder.ThursdayStartTime != scheduleBuilder.SaturdayStartTime && scheduleBuilder.ThursdayStartTime != null && scheduleBuilder.SaturdayStartTime != null || scheduleBuilder.ThursdayEndTime != scheduleBuilder.SaturdayEndTime && scheduleBuilder.ThursdayEndTime != null && scheduleBuilder.SaturdayEndTime != null
|| scheduleBuilder.FridayStartTime != scheduleBuilder.SaturdayStartTime && scheduleBuilder.FridayStartTime != null && scheduleBuilder.SaturdayStartTime != null || scheduleBuilder.FridayEndTime != scheduleBuilder.SaturdayEndTime && scheduleBuilder.FridayEndTime != null && scheduleBuilder.SaturdayEndTime != null
)
{
System.Diagnostics.Debug.Write("Tuesday and Sunday Don't Match!");
scheduleBuilder.DaysMatching = "No";
}
scheduleBuilder.ScheduleSummary = scheduleBuilder.Days + " " + startTime + " | Scheduled Days Match: " + scheduleBuilder.DaysMatching;
}
else
{
var scheduleInDb = _context.ScheduleBuilder.Single(a => a.Id == scheduleBuilder.Id);
scheduleInDb.MondayStartTime = scheduleBuilder.MondayStartTime;
scheduleInDb.TuesdayStartTime = scheduleBuilder.TuesdayStartTime;
scheduleInDb.WednesdayStartTime = scheduleBuilder.WednesdayStartTime;
scheduleInDb.ThursdayStartTime = scheduleBuilder.ThursdayStartTime;
scheduleInDb.FridayStartTime = scheduleBuilder.FridayStartTime;
scheduleInDb.SaturdayStartTime = scheduleBuilder.SaturdayStartTime;
scheduleInDb.SundayStartTime = scheduleBuilder.SundayStartTime;
scheduleInDb.MondayEndTime = scheduleBuilder.MondayEndTime;
scheduleInDb.TuesdayEndTime = scheduleBuilder.TuesdayEndTime;
scheduleInDb.WednesdayEndTime = scheduleBuilder.WednesdayEndTime;
scheduleInDb.ThursdayEndTime = scheduleBuilder.ThursdayEndTime;
scheduleInDb.FridayEndTime = scheduleBuilder.FridayEndTime;
scheduleInDb.SaturdayEndTime = scheduleBuilder.SaturdayEndTime;
scheduleInDb.SundayEndTime = scheduleBuilder.SundayEndTime;
scheduleInDb.MondayFirstBreak = scheduleBuilder.MondayFirstBreak;
scheduleInDb.TuesdayFirstBreak = scheduleBuilder.TuesdayFirstBreak;
scheduleInDb.WednesdayFirstBreak = scheduleBuilder.WednesdayFirstBreak;
scheduleInDb.ThursdayFirstBreak = scheduleBuilder.ThursdayFirstBreak;
scheduleInDb.FridayFirstBreak = scheduleBuilder.FridayFirstBreak;
scheduleInDb.SaturdayFirstBreak = scheduleBuilder.SaturdayFirstBreak;
scheduleInDb.SundayFirstBreak = scheduleBuilder.SundayFirstBreak;
scheduleInDb.MondaySecondBreak = scheduleBuilder.MondaySecondBreak;
scheduleInDb.TuesdaySecondBreak = scheduleBuilder.TuesdaySecondBreak;
scheduleInDb.WednesdaySecondBreak = scheduleBuilder.WednesdaySecondBreak;
scheduleInDb.ThursdaySecondBreak = scheduleBuilder.ThursdaySecondBreak;
scheduleInDb.FridaySecondBreak = scheduleBuilder.FridayFirstBreak;
scheduleInDb.SaturdaySecondBreak = scheduleBuilder.SaturdaySecondBreak;
scheduleInDb.SundaySecondBreak = scheduleBuilder.SundaySecondBreak;
scheduleInDb.MondayLunch = scheduleBuilder.MondayLunch;
scheduleInDb.TuesdayLunch = scheduleBuilder.TuesdayLunch;
scheduleInDb.WednesdayLunch = scheduleBuilder.WednesdayLunch;
scheduleInDb.ThursdayLunch = scheduleBuilder.ThursdayLunch;
scheduleInDb.FridayLunch = scheduleBuilder.FridayLunch;
scheduleInDb.SaturdayLunch = scheduleBuilder.SaturdayLunch;
scheduleInDb.SundayLunch = scheduleBuilder.SundayLunch;
}
_context.SaveChanges();
return RedirectToAction("ScheduleBuilder", "Schedule");
}
ViewModel
public class TierViewModel
{
public IEnumerable<Tier> TierLevel { get; set; }
public ApplicationUser ApplicationUser { get; set; }
public IEnumerable<ShiftLevel> ShiftLevel { get; set; }
public ScheduleBuilder ScheduleBuilder { get; set; }
public IEnumerable<ScheduleBuilder> ScheduleBuilderList { get; set; }
public ScheduleBuilderTier2 ScheduleBuilderTwo { get; set; }
}
I have a large amount of directory type data, with properties like email, telephone, post code etc. I want to detect and group duplicates but on all the multiple properties, where groups can be made up of duplicates on different properties but not all have to be direct duplicates of each other but may be related via another row.
Example data:
Name | Email | Tel | Postcode
John Sim | j#j.com | 111 | C67
J Sim | | 111 |
John S | | | C67
I'd like to be able to find a way that I can detect duplicates over the Email, Tel and Postcode properties but even if they don't all match. So in the example above I'd get all 3 of the above grouped, even though the last one has no directed match to the middle one, but the first shares a match with both.
If that makes sense! obviously that is very simplified, I have a 100's of records I'm trying to group in a way I can display the duplicate groups.
So far I have found some very inefficient ways of doing this, involving going through each row, grouping any direct duplicates, but then checking to see if any of those duplicates also have duplicates and if so move them all together into a new group. But I'm trying to find some inspiration and a more efficient way of doing it :)
Thanks!
You could get the complexity down to O(n) using indexes in a foreach loop and combining on every iteration like the following:
foreach (var entry in list)
{
Group emailGroup = null;
Group telGroup = null;
Group postcodeGroup = null;
if (entry.Email != null && _emailGroups.TryGetValue(entry.Email, out emailGroup))
if (!emailGroup.Add(entry)) emailGroup = null;
if (entry.Tel != null && _telGroups.TryGetValue(entry.Tel, out telGroup))
if (!telGroup.Add(entry)) telGroup = null;
if (entry.Postcode != null && _postcodeGroups.TryGetValue(entry.Postcode, out postcodeGroup))
if (!postcodeGroup.Add(entry)) postcodeGroup = null;
if (emailGroup == null && telGroup == null && postcodeGroup == null)
{
CreateGroup(entry);
continue;
}
CombineGroups(emailGroup, telGroup, postcodeGroup);
}
Of course, you would have to decide + handle what you want to do on collision etc. and if need be, add any Name logic (e.g. Split First Name + Middle + Last) and then do a 2 way Contains on each (quite expensive so might want to look at string indexes)
Full Code + Test
See Method
[Test]
public void Test()
in the following.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FluentAssertions;
using NUnit.Framework;
namespace StackOverflow
{
[TestFixture]
public class Class1
{
private Dictionary<string, Group> _emailGroups;
private Dictionary<string, Group> _telGroups;
private Dictionary<string, Group> _postcodeGroups;
private void CreateGroup(Entry entry)
{
var group = new Group(entry);
if (group.Email != null && !_emailGroups.ContainsKey(group.Email))
_emailGroups[group.Email] = group;
if (group.Tel != null && !_emailGroups.ContainsKey(group.Tel))
_telGroups[group.Tel] = group;
if (group.PostCode != null && !_emailGroups.ContainsKey(group.PostCode))
_postcodeGroups[group.PostCode] = group;
}
private void CombineGroups(Group emailGroup, Group telGroup, Group postcodeGroup)
{
if (emailGroup != telGroup && emailGroup != null && telGroup != null)
{
if (emailGroup.CanCombine(telGroup))
{
emailGroup.Add(telGroup);
UpdateIndexes(emailGroup, telGroup);
telGroup = null;
}
;
}
if (emailGroup != postcodeGroup && emailGroup != null && postcodeGroup != null)
{
if (emailGroup.CanCombine(postcodeGroup))
{
emailGroup.Add(postcodeGroup);
UpdateIndexes(emailGroup, postcodeGroup);
postcodeGroup = null;
}
;
}
if (telGroup != postcodeGroup && telGroup != null && postcodeGroup != null)
{
if (telGroup.CanCombine(postcodeGroup))
{
telGroup.Add(postcodeGroup);
UpdateIndexes(telGroup, postcodeGroup);
postcodeGroup = null;
}
;
}
}
private void UpdateIndexes(Group newGroup, Group oldGroup)
{
Group group;
if (oldGroup.Email != null
&& _emailGroups.TryGetValue(oldGroup.Email, out group)
&& group == oldGroup)
_emailGroups[oldGroup.Email] = newGroup;
if (oldGroup.Tel != null
&& _telGroups.TryGetValue(oldGroup.Tel, out group)
&& group == oldGroup)
_telGroups[oldGroup.Tel] = newGroup;
if (oldGroup.PostCode != null
&& _postcodeGroups.TryGetValue(oldGroup.PostCode, out group)
&& group == oldGroup)
_postcodeGroups[oldGroup.PostCode] = newGroup;
}
public class Group
{
public HashSet<Entry> Entries = new HashSet<Entry>();
public Group(Entry entry)
{
Email = entry.Email;
Tel = entry.Tel;
PostCode = entry.PostCode;
Entries.Add(entry);
}
public string Email { get; set; }
public string Tel { get; set; }
public string PostCode { get; set; }
public bool Matches(Entry entry)
{
if (Email != null && entry.Email != null && entry.Email != Email)
return false;
if (Tel != null && entry.Tel != null && entry.Tel != Tel)
return false;
if (PostCode != null && entry.PostCode != null && entry.PostCode != PostCode)
return false;
return true;
}
public bool Add(Entry entry)
{
if (!Matches(entry))
return false;
Entries.Add(entry);
if (Email == null && entry.Email != null)
Email = entry.Email;
if (Tel == null && entry.Tel != null)
Tel = entry.Tel;
if (PostCode == null && entry.PostCode != null)
PostCode = entry.PostCode;
return true;
}
public bool CanCombine(Group entry)
{
if (Email != null && entry.Email != null && Email != entry.Email)
return false;
if (Tel != null && entry.Tel != null && Tel != entry.Tel)
return false;
if (PostCode != null && entry.PostCode != null && PostCode != entry.PostCode)
return false;
return true;
}
public void Add(Group group)
{
foreach (var entry in group.Entries)
{
Add(entry);
}
}
public override string ToString()
{
var sb = new StringBuilder();
sb.AppendLine($"Key: {Email ?? "null"} | {Tel ?? "null"} | {PostCode ?? "null"}");
foreach (var entry in Entries)
{
sb.AppendLine(entry.ToString());
}
return sb.ToString();
}
}
public class Entry
{
public Entry(string name, string email, string tel, string postCode)
{
Name = name;
Email = email;
Tel = tel;
PostCode = postCode;
}
public string Name { get; set; }
public string Email { get; set; }
public string Tel { get; set; }
public string PostCode { get; set; }
public override string ToString()
{
return $"Entry: {Name ?? "null"} | {Email ?? "null"} | {Tel ?? "null"} | {PostCode ?? "null"}";
}
}
[Test]
public void Test()
{
var list = new List<Entry>
{
new Entry("John S", null, null, "C67"),
new Entry("J Sim", null, "111", null),
new Entry("John Sim", "j#j.com", "111", "C67")
};
_emailGroups = new Dictionary<string, Group>();
_telGroups = new Dictionary<string, Group>();
_postcodeGroups = new Dictionary<string, Group>();
foreach (var entry in list)
{
Group emailGroup = null;
Group telGroup = null;
Group postcodeGroup = null;
if (entry.Email != null && _emailGroups.TryGetValue(entry.Email, out emailGroup))
if (!emailGroup.Add(entry)) emailGroup = null;
if (entry.Tel != null && _telGroups.TryGetValue(entry.Tel, out telGroup))
if (!telGroup.Add(entry)) telGroup = null;
if (entry.PostCode != null && _postcodeGroups.TryGetValue(entry.PostCode, out postcodeGroup))
if (!postcodeGroup.Add(entry)) postcodeGroup = null;
if (emailGroup == null && telGroup == null && postcodeGroup == null)
{
CreateGroup(entry);
continue;
}
CombineGroups(emailGroup, telGroup, postcodeGroup);
}
var groups = _emailGroups.Select(x => x.Value)
.Union(_telGroups.Select(x => x.Value))
.Union(_postcodeGroups.Select(x => x.Value))
.Distinct()
.ToList();
foreach (var grp in groups)
{
Console.WriteLine(grp.ToString());
}
groups.Should().HaveCount(1);
groups.First().Entries.Should().HaveCount(3);
}
}
}
I found that code of #RichTebb is great and it returns the Model attribute DisplayName.
But how to iterate through the all Model Display(Name=) attribute values then?
Thanks for ANY clue!
#RichTebb code
public static class HelperReflectionExtensions
{
public static string GetPropertyDisplayString<T>(Expression<Func<T, object>> propertyExpression)
{
var memberInfo = GetPropertyInformation(propertyExpression.Body);
if (memberInfo == null)
{
throw new ArgumentException(
"No property reference expression was found.",
"propertyExpression");
}
var displayAttribute = memberInfo.GetAttribute<DisplayAttribute>(false);
if (displayAttribute != null)
{
return displayAttribute.Name;
}
// ReSharper disable RedundantIfElseBlock
else
// ReSharper restore RedundantIfElseBlock
{
var displayNameAttribute = memberInfo.GetAttribute<DisplayNameAttribute>(false);
if (displayNameAttribute != null)
{
return displayNameAttribute.DisplayName;
}
// ReSharper disable RedundantIfElseBlock
else
// ReSharper restore RedundantIfElseBlock
{
return memberInfo.Name;
}
}
}
public static MemberInfo GetPropertyInformation(Expression propertyExpression)
{
Debug.Assert(propertyExpression != null, "propertyExpression != null");
var memberExpr = propertyExpression as MemberExpression;
if (memberExpr == null)
{
var unaryExpr = propertyExpression as UnaryExpression;
if (unaryExpr != null && unaryExpr.NodeType == ExpressionType.Convert)
{
memberExpr = unaryExpr.Operand as MemberExpression;
}
}
if (memberExpr != null && memberExpr.Member.MemberType == MemberTypes.Property)
{
return memberExpr.Member;
}
return null;
}
public static T GetAttribute<T>(this MemberInfo member, bool isRequired)
where T : Attribute
{
var attribute = member.GetCustomAttributes(typeof(T), false).SingleOrDefault();
if (attribute == null && isRequired)
{
throw new ArgumentException(
string.Format(
CultureInfo.InvariantCulture,
"The {0} attribute must be defined on member {1}",
typeof(T).Name,
member.Name));
}
return (T)attribute;
}
}
Sample:
string displayName = ReflectionExtensions.GetPropertyDisplayName<SomeClass>(i => i.SomeProperty);
3 hours and I found the solution.
First of all
[Display(Name = "Employed: ")]
public Nullable<bool> Employed { get; set; }
and
[DisplayName("Employed: ")]
public Nullable<bool> Employed { get; set; }
are not the same. :) For MVC we have to use this syntax [DisplayName("Employed: ")]
Also the class metadata attribute should look like
[MetadataType(typeof(PatientMetadata))]
public partial class Patient
{
....
internal sealed class PatientMetadata
{
And finally the CODE
public static class DisplayNameHelper
{
public static string GetDisplayName(object obj, string propertyName)
{
if (obj == null) return null;
return GetDisplayName(obj.GetType(), propertyName);
}
public static string GetDisplayName(Type type, string propertyName)
{
var property = type.GetProperty(propertyName);
if (property == null) return null;
return GetDisplayName(property);
}
public static string GetDisplayName(PropertyInfo property)
{
var attrName = GetAttributeDisplayName(property);
if (!string.IsNullOrEmpty(attrName))
return attrName;
var metaName = GetMetaDisplayName(property);
if (!string.IsNullOrEmpty(metaName))
return metaName;
return property.Name.ToString(CultureInfo.InvariantCulture);
}
private static string GetAttributeDisplayName(PropertyInfo property)
{
var atts = property.GetCustomAttributes(
typeof(DisplayNameAttribute), true);
if (atts.Length == 0)
return null;
var displayNameAttribute = atts[0] as DisplayNameAttribute;
return displayNameAttribute != null ? displayNameAttribute.DisplayName : null;
}
private static string GetMetaDisplayName(PropertyInfo property)
{
if (property.DeclaringType != null)
{
var atts = property.DeclaringType.GetCustomAttributes(
typeof(MetadataTypeAttribute), true);
if (atts.Length == 0)
return null;
var metaAttr = atts[0] as MetadataTypeAttribute;
if (metaAttr != null)
{
var metaProperty =
metaAttr.MetadataClassType.GetProperty(property.Name);
return metaProperty == null ? null : GetAttributeDisplayName(metaProperty);
}
}
return null;
}
}
How to use:
var t = patient.GetType();
foreach (var pi in t.GetProperties())
{
var dn = DisplayNameHelper.GetDisplayName(pi);
}
DONE!!!!
Type t = model.GetType();
foreach (PropertyInfo pi in t.GetProperties())
{
var attr = pi.GetCustomAttribute(DisplayNameAttribute, true);
if (attr != null) ...
}