0

I need to generate some hour accounts if they don't exist and tried to make the method as easy as possible. Unfortunately I'm stuck at the following.

This is how I would check / create an account for every month:

// January

if (!_db.Stundenkonto.Any(x => x.MitarbeiterId == mitarbeiterId && x.Jahr == jahr && x.Monat == 1))     
{
  HrsAccount acc = new HrsAccount 
  {
    AccountId = new Guid(),
    UserId = loggedInUser,
    Month = 1 <<--- This is where I'd need the number of the Enum (1),
    HoursToWork = model.data[0].january <<--- Here I'd need the name of the Enum
    HoursWorked = model.data[1].january <<-- Same here
  }
}

So as you can see I need number AND value of the Enum. I tried:

foreach (MonthEnum month in Enum.GetValues(typeof(MonthEnum)))
{
    HrsAccount acc = new HrsAccount 
  {
    AccountId = new Guid(),
    UserId = loggedInUser,
    Month = (double)month,
    HoursToWork = model.data[0].month <<-- Gives errors
    HoursWorked = model.data[1].month <<-- on these two
  }
}

Is it possible to get this working as I need it?

Edit: Sorry here is the Enum:

public enum MonthEnum
{
    january = 1,
    february,
    march,
    april,
    may,
    june,
    july,
    august,
    september,
    oktober,
    november,
    december
}

model.data are 4 arrays. They are all the same except one holds the hours the employee has to work, the other one how much the employee worked. The others are just calculations of those so they look like this:

model.data[0]: <<-- Hours he has to work

january: 60,
february: 120,
january: 120
march: 175,
april: 165,
may: 176,
june: 186,
july: 176,
august: 176,
september: 140,
october: 120,
november: 110,
december: 146

model.data[1] <<-- how much he actually worked

model.data[2] <<-- how many hrs were paid

model.data[3] <<-- difference between hrs he should work and hrs he worked

model.data[4] <<-- difference last month

rawk
  • 508
  • 1
  • 7
  • 13

2 Answers2

3

Assuming your classes look like this:

public class ModelClass
{
    // Other parts of the class
    public DataClass[] data;
    // Other parts of the class
}

public class DataClass
{
    public int january;
    ...
    public int december;
}

I would say the easiest way to make them accessible like you wish would be to change the data class to something like

public class DataClass
{
    public int[12] hoursByMonth;
}

This way you could access them by month index and not by name:

foreach (MonthEnum month in Enum.GetValues(typeof(MonthEnum)))
{
    HrsAccount acc = new HrsAccount 
    {
        AccountId = new Guid(),
        UserId = loggedInUser,
        Month = (int)month,
        HoursToWork = model.data[0].hoursByMonth[((int)month) - 1],
        HoursWorked = model.data[1].hoursByMonth[((int)month) - 1]
    }
}

In case this is not possible, maybe something I found in this question might help

string enumName = Enum.GetName(typeof(MonthEnum), month);
HoursToWork = model.data[0].GetType().GetField(enumName).GetValue(model.data[0]);

EDIT To fix your error you could try this

HoursToWork = double.Parse(model.data[0].GetType().GetField(enumName).GetValue(model.data[0]).ToString());

Note however, that if the string for some reason can't be parsed, it will throw an exception. This fixes that:

foreach (MonthEnum month in Enum.GetValues(typeof(MonthEnum)))
{
    double hoursToWork;
    double hoursWorked;
    string enumName = Enum.GetName(typeof(MonthEnum), month);
    bool x = double.TryParse(model.data[0].GetType().GetField(enumName).GetValue(model.data[0]).ToString(), out hoursToWork);
    bool y = double.TryParse(model.data[0].GetType().GetField(enumName).GetValue(model.data[1]).ToString(), out hoursWorked);

    // If either of the TryParse fails, don't create a model due to false Data
    if(!x || !y) continue;

    HrsAccount acc = new HrsAccount
    {
        AccountId = new Guid(),
        UserId = loggedInUser,
        Month = (int)month,
        HoursToWork = hoursToWork,
        HoursWorked = hoursWorked
    };
}

EDIT 2
.GetField(enumName) has to be swapped for .GetProperty(enumName) depending on whether what you're trying to access is a field or a property.

IDarkCoder
  • 709
  • 7
  • 18
  • 3
    Note that a `Dictionary` might be nicer to work with than a `int[12]`. Less prone to error if e.g. some people don't work every month. – Flater Aug 27 '18 at 13:33
  • @IDarkCoder Thanks for the reply! I didn't want to change the structure so I tried your last suggestion. This gives me the error "Cannot implicitly convert type 'object' to 'double'". Looks like I need to change it after all. Need to read up on Dictionaries because I pretty much liked the suggestion from Flater above – rawk Aug 27 '18 at 13:52
  • 1
    @rawk I updated the answer to adapt to the converting error. My bad for that – IDarkCoder Aug 28 '18 at 06:21
  • 1
    @IDarkCoder Thank you so much!! I couldn't get this working at first and spent some time debugging. I realized that when using .GetField(enumName) did not work because the compiler created a field called k_backingfield. After some research I found out that when using .GetProperty(enumName) works as this reflects the actual name. Made my day. Thanks again :) – rawk Aug 28 '18 at 08:25
  • 1
    @rawk I forgot to mention that. I updated the answer to make it obvious for others with the same problem. – IDarkCoder Aug 28 '18 at 08:43
0

If I understand you correctly you need to get the name of the current enum value? You can do this using https://msdn.microsoft.com/de-de/library/system.enum.getname(v=vs.110).aspx

string name = Enum.GetName(typeof(MyEnum), 3)

Further you can use following to get the represented integer value:

var x = (int)MyEnum.AAAA;
  • Yeah that's how I got it but if you want to take a look at the updated question, you will see that I need to use the enum value to access the property of my model.data[x]. I found it difficult to explain sorry :| – rawk Aug 27 '18 at 12:56