6

I have these two classes:

public class Message
{
    string Message;
    string Code;
}

public class MessageInitializer
{
    DataSet ds;
    DataRow dr;
    message[] ms;
}

I want to create a constructor in MessageInitializer like this:

MessageInitializer()
{
    this.ms = new Message[ds.Tables[0].Rows.Count];
    for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
    {
        dr = ds.Tables[0].Rows[i];
        ms[(string)dr.ItemArray[0]] = (string)dr.ItemArray[1];
    }
}

But array's index must be int type. I have no idea how to work this out:

ms[(string)dr.ItemArray[0]] = (string)dr.ItemArray[1];

Update:

Code format is a string like this: [001-001-001], so I can't convert it to integer.

9
  • 1
    try Integer.parseInt(dr.ItemArray[0]) Commented Jul 26, 2015 at 4:28
  • 4
    Sounds to me like you're looking for a Dictionary. Commented Jul 26, 2015 at 4:38
  • 1
    dr.ItemArray[0] is code and dr.ItemArray[1] is message? Commented Jul 26, 2015 at 4:39
  • 1
    What string do you have in dr.ItemArray[0]? {001-001-001]? Commented Jul 26, 2015 at 4:43
  • 1
    Is there a reason you want to use Array<Message> and not Dictionary<string, Message>? Commented Jul 26, 2015 at 4:46

4 Answers 4

5

you don't need Message class any more. Using a dictionary as follows solves the problem :

public class MessageInitializer
{
    DataSet ds;
    DataRow dr;
    Dictionary<string, string> ms;
    public MessageInitializer()
    {
        this.ms = new Dictionary<string,string>(ds.Tables[0].Rows.Count);
        for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
        {
            dr = ds.Tables[0].Rows[i];
            ms[(string)dr.ItemArray[0]] = (string)dr.ItemArray[1];
        }
    }
}

I hope this would be helpful.

Sign up to request clarification or add additional context in comments.

3 Comments

Would be easier this way. Unless he wants to extend Message later by adding new properties.
That's right my friend. In this case using a list is the solution.
But as you said above the performance of the dictionaries are much better.
3

If you just want to get a list of all the messages from the database, then you can use the code below. Note, List instead of Array. Easier to use and faster.

public class Message
{
    string Message;
    string Code;
}

public class MessageInitializer
{
    DataSet ds;
    DataRow dr;
    List<Message> ms;

    MessageInitializer()
    {
        this.ms = new List<Message>();
        for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
        {
            dr = ds.Tables[0].Rows[i];
            ms.Add(new Message
            {
                 Code = dr.ItemArray[0].ToString(),
                 Message = dr.ItemArray[1].ToString(),
            });
        }
    }
}

You mentioned that you have couple million records. List will perform fine in case you want to access items sequestially. If you want to access items in a non-sequential manner, I suggest you use Dictionary instead (to improve search perfromance):

public class MessageInitializer
{
    DataSet ds;
    DataRow dr;
    Dictionary<string, Message> ms;

    MessageInitializer()
    {
        this.ms = new Dictionary<string, Message>();
        for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
        {
            dr = ds.Tables[0].Rows[i];
            ms.Add(dr.ItemArray[0].ToString(), new Message
            {
                 Code = dr.ItemArray[0].ToString(),
                 Message = dr.ItemArray[1].ToString(),
            });
        }
    }
}

You can access message as follows:

var message = ms["001-001-001"];

It will be orders or magnitude faster than accessing a random List item:

var message - ms.First(x => x.Code == "001-001-001");

5 Comments

thank you so much. now how can access the single message with code? i have to use a loop. am i right?
are you sure? when I tried ms["001-001-001"] this error showed up: Error 2 Argument 1: cannot convert from 'string' to 'int'.
My bad. I was thinking about a Dictionary. With List you can do ms.First(x => x.Code == "001-001-001").
thank you so much. i red about dictionary. seems its just what i want. please edit your post and mention dictionary in it so i can marked as answer.
Yeah, added a sample that uses Dictionary.
3

I think you just want build an array of messages from ds.Tables[0]

Code -
ms[i].Code = (string)dr.ItemArray[0];

Message -
ms[i].Message = (string)dr.ItemArray[1];

MessageInitializer()
{
    this.ms = new Message[ds.Tables[0].Rows.Count];
    for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
    {
        dr = ds.Tables[0].Rows[i];
        ms[i].Code= (string)dr.ItemArray[0];
        ms[i].Message = (string)dr.ItemArray[1];
    }
}

For better performance make use of Parallel.ForEach -

Parallel.ForEach(ds.Tables[0].AsEnumerable(), row => {
        ms[i].Code= (string)row.ItemArray[0];
        ms[i].Message = (string)row.ItemArray[1];
});

5 Comments

currently my class work exactly like this. in order to access the message in class i have a foreach and because of millions of messages in it, it works really slow. so i decided to change the class.
@Dan do you really have to load millions of messages from you database in memory?
@AseemGautam. yes. currently it takes about 800 milliseconds to find the message and i hope i can make it faster.
@NikolaiSamteladze. unfortunately yes. i have to do it.
@Dan do you process them somehow afterwards? If so, you might want to do it in batches (say 10000 each) not to keep such large structures in memory.
1

I think what you want to perform is the following:

public class Message
{
    public string message { get; set; }
    public string code { get; set; }

}

public class MessageInitializer
{
    DataSet ds;
    DataRow dr;
    Message[] ms;

    MessageInitializer()
    {
        this.ms = new Message[ds.Tables[0].Rows.Count];
        for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
        {
            dr = ds.Tables[0].Rows[i];
            ms[i] = new Message
            {
                code = (string)dr.ItemArray[0],
                message = (string)dr.ItemArray[1]
            };
        }
    }
}

1 Comment

Dan, to find a single message by code, you ca use: var myMessage = ms.SingleOrDefault(item => item.code == someCode);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.