Jump to content
Xtreme .Net Talk

Recommended Posts

Posted (edited)

This is a technical one that is above me...

 

I've got a custom class I made that uses a lot of external procedures from mpr.dll. Basically I get the values I need from them and put them into what use to be a struct and return the struct to the program that requires them. The struct is very simple... it contains to string properties.

 

The problem I am having is that when I take those strings and use them in just about anything (such as a database) the strings get corrupted somehow and the data is lost, this doesn't happen if I put it into a control that has a list collection such as a ListBox or ListView. I thought that maybe this was because I was passing it back via a struct, so I changed my struct that I'm passing back into a class and the same problem occurs, so now I'm wonder if rather than a static method I should be using a regular method. Below is an example of what is happening...

 

//MYTEST.DLL
//I put both the struct and the class... in actuallity it's either one or the other...same with procedures
//I just wanted to show for example...
public strcut Demo1
{
    public string ItemX;
    public string ItemY;
}
public class Demo2
{
    private string ix = "";
    private string iy = "";
    public string ItemX;
    {
         get { return ix; }
         set { ix = value; }
    }
    public string ItemY;
    {
         get { return iy; }
         set { iy = value; }
    }
    public Demo2()
    {
         //no initialization
    }
}
public Class DoDemo
{
    public Demo()
    {
          //no initialization
    }
    public static Demo1[] GetItems()
    {
          Demo1[] items;
         //Code that does the external procedures and sets items
         return items;
    }
    public static Demo2[] GetItems()
    {
         Demo2[] items;
         //Code that does the external procedures and sets items
         return items;
    }
}
//The calling program looks like this:
public SomeProcedure()
{
    Demo1[] d1 = DoDemo.GetItems();
    foreach(Demo1 d in d1)
    {
          DataRow r = myTable.NewRow();
          r[0] = d.ItemX;
          r[1] = d.ItemY;
          myTable.Rows.Add(r);
    }
    myDataAdapter.Update();
}

 

If the actual values returned by the procedure were:

 

TEST123

SOMEBODY

ANYTHING

FOUR

EXTERNAL

 

What would go into the database is the following:

 

TEST123

SOMEBOD

ANYTHIN

FOURHIN

EXTERNA

 

Notice that because the first return string was a length of 7, it truncated all other strings to 7 if they were longer, if they were less it appended the remaining letters from a previous value that has 7 characters.

 

Now if instead of the above procedure I was to have:

 

public SomeProcedure()
{
    Demo1[] d1 = DoDemo.GetItems();
    foreach(Demo1 d in d1)
    {
          myListView.Items.Add(d.ItemX);
          myListView.Items[myListView.Items.Count - 1].Tag = d.ItemY;
    }
}

 

Everything would display proper on the control. And what this is the crap I'm doing now to get things to work... I put everything into a hidden ListView and then from the ListView into a database... absolutely horrendous programming; I know this! And I want to fix it! - (update) Actually read my update below, only the next paragraph works, the above actually results in the same problem. (/update)

 

I also can move my DataAdapter.Update() method into the foreach loop, but that causes such large program lag that I rather just leave the horrendous programming to be honest with you.

 

This scope/reference problem I'm having is driving me up the wall. I'm willing to send the actually DLL that is doing this to someone who is knowledgable enough about using external procedures that use a lot of marshalling and memory management to fix the problem. This will be a great learning experience for me because I'm lost on this one.

 

 

Thanks!

Edited by bri189a
Posted (edited)

the data adapter set-up statement looks similiar to this, the real one has more fields and a primary key, but again to keep it simple... also in the database in case your wondering the string length is set to 50:

 


//Insert Commands [..]
da.InsertCommand = new OleDbCommand("ADD_DEMO", myConn);
da.InsertCommand.CommandType=CommandType.Procedure;
da.InsertCommand.Parameters.Add("@ItemX", OleDbType.Char, 50, "ItemX");
da.UpdateCommand.Parameters.Add("@ItemY", OleDbType.Char, 50, "ItemY");

//Update Commands [..]

//Delete comands [..]

Edited by bri189a
Posted

Okay then, that answers my first questions.

 

Now, did you interrogate the data-table before you issue the Update on your data-adapter to see that the values there are as expected?

Posted (edited)

I'll tell you this... I added the OnUpdating Event and looked at the parameters as they are going in and they look correct - at least in the Locals window - hope that was what you were asking for, I was on the track that maybe the database was corrupted or something too originally... but like I said, calling Update() during the for loop doesn't have any problems, and I went back and tested, and actually adding the values to a list box and then putting them in the database actually has the same problem, unless of coarse I move the update into the for loop where I'm now going through the listbox list. It's the strangest thing I've ever seen... thanks for helping on this btw...

 

Also, fyi, I'm pretty much using a copy and paste of other databases I've done that have worked fine, but don't use that api wrapper class. The table in this dataset I was originally using FillSchema with, but thinking that might of been the problem I stopped using that and made the information via code myself, but that resulted in the same problem.

Edited by bri189a
Posted (edited)

Also, I did the following; I changed from CommandType.StoredProcedure to CommandType.Text and in my RowUpdating Event I changed my SQL text as needed so the rows would be updated, this worked perfectly as expected. I don't know what's going on with this thing.

 

Also I tried a whole new database building from scratch, same thing.

Edited by bri189a
Posted
Well it's deffinitely that custom class, I can pass just strings in an array and everything works like it should. I've tried Copy and Clone, but no matter what it seems as if there's a reference problem in my custom class that whenever I'm trying to save the property it gets this problem. I don't know how to fix it. Any volunteers? I'll send the entire source code. It's a great class, get's your domains and computers on a domain easily and as quick as network neighborhood does.
Posted

I got a quick chance to walk through the code and it seems like your datatable is the cause of truncation.

 

I put a breakpoint on: DOMAINS.Update(ds, "DOMAINS");

 

and in command window:

? ds.Tables["DOMAINS"].Rows[1].ItemArray[1]

"ODO1S"

 

which should be "ODO1SIMULATOR"

 

I'll see later if I can narrow this down some more - perhaps if you create a schema for your data-table it would work?

Posted

Thanks for looking... I've tried using FillSchema(), building the schema manually, having no schema at all and lettin ADO take care of it, it all comes out the same; I'm glad to hear though that it's happening on someone else's computer...now I don't feel completely insane.

 

Here's a list of things I've tried and have failed, but please try again if you think it will work - I could've screwed it up:

 

-Take out the dataset and just using the table

-Use SQL text with parameters

-Rebuilding the database from scratch

-Changing the names of the parameter to something totally differant from the column

-not using the @ symbol

-unencrypting the database

-explicitly telling the shcema that the string length if 50 (which it showed up in the schema anyway...but...had to try)

 

Things that did work:

-Putting Update() in for loop - takes the point out of disconnected data though...

 

-Having SQL text like the following:

"INSERT INTO DOMAINS (DomainName, Track) VALUES ('{DomainName}', {Track})"

and then putting in the RowUpdatingEvent()

string s = da.UpdateCommand.CommandText;

s = s.Replace("{DomainName}", e.Row["DomainName"]);

s = s.Replace("{Track}", e.Row["Track"]);

da.UpdateCommand.CommandText = s;

---now that is just plain silly and horrible, but it worked!

 

I'm grateful for any help any of you find!

 

Brian

Posted

Now this is weird - I created a new Access database with one table like your, and then added your queries. I didn't apply any security, etc to the file, and everything ran exactly as I expected.

 

Now, when I started to model my table after yours, as soon as I set the DomainName.Required = Yes (from default of No value), I got the error you got.

 

So, I deleted the table and re-added the same layout, just setting the column names and data-types (left all else as default).

Posted
Unfortunately that didn't work for me; I deleted the table, then re-made the table, using defaults for each column (just changed the yes/no type to true/false - did you do that?, and made ID auto number and primary key), and still same thing... like I said though, I'm glad to see it's just not me, thanks for your help with this, let me know if you find anything else!
Posted
Try creating a new Access file and re-create your table (with defaults to start - then tweak your columns)/stored procs in that file. That's the way I got it to work.
Posted

I figured it out! I figured it out!

 

I'm excited about this... in the parameter for "DOMAIN" ("@DomainName"), change the length from 50 to 0... don't know why... makes it work though... I'm going to research later, because I do want to know why!!!!!! Anyone who would know why, please share the wealth!

 

Thanks PD and mocella for your help through this... I'm like 4 days behind now, but now I can code correctly...THANKS AGAIN :D

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...