1. Saul Erhmy
  2. .NET DataStore
  3. Monday, 10 October 2022 16:01 PM UTC

Hi!

I know I can create a datastore by doing new Datastore<myDW>(MyOracleconnection)  but im looking to create a new DataStore from its attribute string, something like this new DataStore("myDWattribute"); Trying to do this throws an error "No metadata for DataWindow 'myDWattribute' found". My goal is to create a string array with the attributes and use that to initialize a new DataStore. 

Accepted Answer
Francisco Martinez @Appeon Accepted Answer Pending Moderation
  1. Tuesday, 11 October 2022 13:58 PM UTC
  2. .NET DataStore
  3. # Permalink

Hi Saul,

When you convert a DataWindow to SnapDevelop, the converter generates a C# decorated similar to the following:

Note the [DataWindow("d_address", DwStyle.Grid)] attribute.

This is the name you have to use when creating a non-generic DataStore.

So in this case you would have to do it like this:

var dataStore = new DataStore("d_address", dataContext);

 

Regards,
Francisco

Comment
  1. Saul Erhmy
  2. Friday, 14 October 2022 16:36 PM UTC
@Logan, thank you sir that worked! Now I just need to see if I can make that work in my for loop for creating threads! All the Best
  1. Helpful
  1. Saul Erhmy
  2. Friday, 14 October 2022 16:52 PM UTC
Im still getting the "Object reference not set to an instance of an object" for some of the threads for some reason so I'll have to figure out what is causing that.
  1. Helpful
  1. Saul Erhmy
  2. Friday, 14 October 2022 18:27 PM UTC
Got it working
  1. Helpful
There are no comments made yet.
Logan Liu @Appeon Accepted Answer Pending Moderation
  1. Tuesday, 11 October 2022 09:15 AM UTC
  2. .NET DataStore
  3. # 1

Hi Saul,

I don't understand "create a new DataStore from its attribute string". What's the attribute string?

For your code new DataStore("myDWattribute"), is "myDWattribute" a correct datawindow object name?

Refer to: https://docs.appeon.com/net_datastore/4.x/api_reference/DWNet.Data/DataStore/DataStore/Constructor/DataStore2.html

 

Please refer to the API documentation to learn all constructors of .NET DataStore:

Generic .NET DataStore:

https://docs.appeon.com/net_datastore/4.x/api_reference/DWNet.Data/DataStore/DataStore_Generic/DataStore_Generic.html

Non-generic .NET DataStore:

https://docs.appeon.com/net_datastore/4.x/api_reference/DWNet.Data/DataStore/DataStore/Constructor/DataStore.html

 

Regards,

Logan

Comment
There are no comments made yet.
Francisco Martinez @Appeon Accepted Answer Pending Moderation
  1. Wednesday, 12 October 2022 15:15 PM UTC
  2. .NET DataStore
  3. # 2

Hi Saul,

I'm posting this in this thread to have the solution be in the respective post.
The reason you're getting the "No metadata for DataWindow 'myDWattribute' found" is because the Web API hasn't looked for the classes decorated with the attribute DataWindow("myDWattribute"...).

You need to configure your application to use the DataWindows.

To do this:

1. Add the DWNet.Data.AspNetCore nuget package to your project
2. (I'm asuming you're on .NET 6) In the Program.cs file, at the top add:

 

using DWNet.Data.AspNetCore;

and after the var app = builder.Build(); line add

app.UseDataWindow();

This will register the classes decorated with the DataWindow attribute and make "myDWattribute" findable.

This should solve your issue.

Regards,
Francisco

Comment
  1. Saul Erhmy
  2. Thursday, 13 October 2022 18:26 PM UTC
Hi Francisco,

Thanks again for your response. Everything is making sense and what needs to be done to resolve my issue except the "var app = builder.Build();" line. I'm confused what it does and how to implement it. I never used that line in my code. I was doing more research online and it seems I need something called a IApplicationBuilder. I'm not sure if this piece of information is relevant but im only using a console app right not and I have a regular Main(string[] args).



I saw I can do something like -

public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.UseDataWindow(); }

but I am not sure how to call this function (what to use for the app and env parameters) from my Main(string[] args). Am I going about this the wrong way?



And is this the only way to register the classes with the DataWindow attribute?



Thanks for your time,

Saul
  1. Helpful
  1. Francisco Martinez @Appeon
  2. Thursday, 13 October 2022 18:43 PM UTC
Hi Saul, I thought you were working with a ASP.NET Core API, not on a Console App, my apologies. I believe it's not possible to use the non-generic .NET DataStore outside of a ASP.NET Core API project, but I'll ask around and let you know what I find out. In the meantime you'll have to work with the generic version. May I ask what is it you're trying to accomplish? To see if it can be done in some other way.

Regards - Francisco
  1. Helpful
  1. Saul Erhmy
  2. Thursday, 13 October 2022 19:38 PM UTC
No Problem, Let me know if you find out! I'll try my best to explain what I am trying to accomplish. I hope this doesn't format weird..



I have 10 different DataStores, my goal is to create 10 Threads - one for each DataStore. I want to create these threads in a loop and call a function, I'll call it ExportData(DataStore datastore).



My original idea was something like this

string[] datastoreAttributeNames = {"dw1Attribute", "dw2Attribute"};

for (int i = 0; i < DatastoreAttributeNames.Count; i++)

{

var datastore = new DataStore(DatastoreAttributeNames[i], Oracleconnection);

Thread myThread = new Thread(() => ExportData(datastore));

myThread.Start();

}



So i guess how can I pass different DataStores each increment of the loop. Now I am thinking maybe get an array of DataStores - Datastore[] ARGdataStore = new DataStore[10]; - but I'm not sure how i could add different datastores to that array. If I can somehow call ARGdataStore[0] and that be DW1 and then call ARGdataStore[1] and that be DW2 i think my problem would be solved.



Right now my code is chunky and repetitive because I have to create each thread manually and create a new ExportData(DataStore datastore) function for each DataWindow - even though every ExportData function has the same code. I'll use two datastores as an example. These are the function definitions. ExportData01(DataStore<DWone> datastore), ExportData02(DataStore<DWtwo> datastore)



{

var datastore01 = new DataStore<DWone>(Oracleconnection);

var datastore02 = new DataStore<DWtwo>(Oracleconnection);



Thread thread1 = new Thread(() => ExportDataOne(datastore01);

Thread thread2 = new Thread(() => ExportDataTwo(datastore02));



thread1.Start();

thread2.Start();

}



ExportData01(DataStore<DWone> datastore) { 100 lines of code }

ExportData02(DataStore<DWone> datastore) { 100 lines of same code as ExportData01 }



You can see how redundant this would get for 10 threads/DataStores. If I want to add more DataStores in the future it would be even more repetitive. Each ExportData##(...) does the same thing the only difference between them is the DataStore being used.
  1. Helpful
There are no comments made yet.
Francisco Martinez @Appeon Accepted Answer Pending Moderation
  1. Thursday, 13 October 2022 20:19 PM UTC
  2. .NET DataStore
  3. # 3

Depending on the operations you perform to the .NET DataStores inside ExportData(...) you might be able to get away with using polymorphism to work with all your DataStores

Both generic .NET DataStore and non-generic .NET DataStore implement IDataStoreBase so hopefully the methods you call on the DataStores are within this interface.

You could do it like this:

public void Main(string[] args) {
    var dataStores = new List<IDataStoreBase>{
        new DataStore<DWone>(_dbContext),
        new DataStore<DWtwo>(_dbContext),
        // <etc>
    };

    foreach(var dataStore in dataStores) {
        new Thread(() => ExportData(dataStore))
            .Start();
    }
}

private void ExportData(IDataStoreBase dataStore) {
    // Do stuff with the dataStores
}

 

Regards,
Francisco

Comment
  1. Francisco Martinez @Appeon
  2. Thursday, 13 October 2022 20:23 PM UTC
You might also be able to instantiate the .NET DataStores' names (strings) but that goes a bit too deep into C# reflection
  1. Helpful 1
  1. Saul Erhmy
  2. Thursday, 13 October 2022 21:30 PM UTC
Thanks! I think thats something I'm looking for. Im almost able to implement it. This is what I have so far



using (var Oracleconnection = new ODataContext(connectionString))

{

var dataStores = new List<IDataStoreBase>

{

new DataStore<DWOne>(Oracleconnection),

new DataStore<DWTwo>(Oracleconnection)



};



for (int i = 0; i < dataStores.Count; i++)

{

ExportDataStore x = new ExportDataStore();

int threadIdent = i;



Thread myThread = new Thread(() => x.ExportData(threadIdent, dataStores[threadIdent]));

myThread.Start();

threads[i] = myThread;

}



foreach (var thread in threads)

{

thread.Join();

}

}



public void ExportData(int id, IDataStoreBase dataStore)

{

int row = dataStore.Retrieve();

Console.WriteLine("ThreadId: " + id + " Row: " + row);

}



DWOne Works and Retrieves perfectly fine but for DWtwo I get this error when calling the retrieve "Object reference not set to an instance of an object." Im going to keep experimenting because I feel like Im close but can you see anything that stands out that could cause this exception?



Thanks,

Saul
  1. Helpful
There are no comments made yet.
  • Page :
  • 1


There are no replies made for this question yet.
However, you are not allowed to reply to this question.