Solved

Need help with C# - creating a generic class to update different tables

  • 27 June 2023
  • 6 replies
  • 169 views

Userlevel 6
Badge +3

I created about 50 different methods that update different tables.  The code in them is exactly the same, except the table names and field names are different.

I know this is really a C# question, but I am not very good with C#.  I’ve looked at the Acumatica repository to try to see how to do it, but I am pretty darn ignorant about how to do it.

Below you will see the code that is hard coded with the table and fields.  It is the code after the //all this stuff is hard coded comment.  

I want to create a generic method I can call that would accept the table name and field name as parameters.

Here is a signature for what I *think* is what I need to have.  At a minimum, I got something to compile.

How do I replace the hard coded table names and field names?  Is this an easy thing to do?

My application works fine with 50 different methods (each having the table name and field name hard coded), but this would make my app more “professional”.

		public static List<T> TableUpdate<T, TField>(MergeViews graph, int bAccountFrom, int bAccountTo)
where TField : class, IBqlField
where T : class, IBqlTable
{

//all this stuff is hard coded
APInvoice exists = SelectFrom<APInvoice>.Where<APInvoice.suppliedByVendorID.IsEqual<@P.AsInt>>.View.Select(graph, bAccountFrom);
if (exists != null)
{
if (!PXDatabase.Update<APInvoice>(
new PXDataFieldAssign(typeof(APInvoice.suppliedByVendorID).Name,
PXDbType.Int, bAccountTo),
new PXDataFieldRestrict(typeof(APInvoice.suppliedByVendorID).Name,
PXDbType.Int, bAccountFrom)))
{
throw new PXException(ICSMessages.UpdateFailed, "APInvoice-suppliedByVendorID",
typeof(APInvoice).Name);
}
}

return null;
}

Thanks in advance for any insights you can offer.

icon

Best answer by davidnavasardyan09 28 June 2023, 05:14

View original

6 replies

Userlevel 5
Badge +1

The Acumatica Framework's BQL and DACs are strongly typed and usually do not support dynamic table names and fields. Your approach to using generics in the function is a common way to perform similar actions on different types of tables in Acumatica.

However, with your existing method, you'll still need to call this method for each table individually. The method should work for updating a specified field in any table, assuming the field and table meet the conditions in your where clause.

Here's an updated version of your method, which uses generics to perform the same action on any table/field:

 

public static void TableUpdate<T, TField>(PXGraph graph, int bAccountFrom, int bAccountTo)
where TField : IBqlField
where T : class, IBqlTable, new()
{
// Build the BQL Command
var bqlCommand = BqlCommand.CreateInstance(typeof(Select<,>),
typeof(T),
typeof(Where<,>),
typeof(TField),
typeof(Equal<Required<TField>>));

// Create a View and Select the existing data
var view = new PXView(graph, true, bqlCommand);
var existingRecord = view.SelectSingle(bAccountFrom);

if (existingRecord != null)
{
if (!PXDatabase.Update<T>(
new PXDataFieldAssign(typeof(TField).Name, PXDbType.Int, bAccountTo),
new PXDataFieldRestrict(typeof(TField).Name, PXDbType.Int, bAccountFrom)))
{
throw new PXException(ICSMessages.UpdateFailed, $"{typeof(T).Name}-{typeof(TField).Name}",
typeof(T).Name);
}
}
}

You would call this method with specific table and field like this:

TableUpdate<APInvoice, APInvoice.suppliedByVendorID>(graph, bAccountFrom, bAccountTo);

 

Userlevel 6
Badge +3

@davidnavasardyan09 I am going to be able to leverage this code in many other places.  

I love you man!  Thank you!!

Userlevel 6
Badge +3

@davidnavasardyan09 after putting that code in and digesting it, it makes great sense.  You have taught me several things about how to do things with C#.  I’m a VB developer by trade, but I do OK in C#.  What you did for me is above and beyond the call of duty.  I can[t thank you enough for what the work you saved me.  I’m absolutely certain that this methodology will save me in the future.  

Userlevel 5
Badge +1

@davidnavasardyan09 after putting that code in and digesting it, it makes great sense.  You have taught me several things about how to do things with C#.  I’m a VB developer by trade, but I do OK in C#.  What you did for me is above and beyond the call of duty.  I can[t thank you enough for what the work you saved me.  I’m absolutely certain that this methodology will save me in the future.  

I'm really glad to hear that you found the code and explanations helpful! It's always a pleasure to assist and share knowledge, especially when it can make someone's work easier. As a VB developer, you already have a great foundation in programming and I'm sure you'll continue to do well in C#. Remember, every language is just a tool - the key is understanding the concepts. Don't hesitate to reach out if you have any more questions or if there's anything else I can help you with in the future. Happy coding!

@davidnavasardyan09 after putting that code in and digesting it, it makes great sense.  You have taught me several things about how to do things with C#.  I’m a VB developer by trade, but I do OK in C#.  What you did for me is above and beyond the call of duty.  I can[t thank you enough for what the work you saved me.  I’m absolutely certain that this methodology will save me in the future.  

I'm really glad to hear that you found the code and explanations helpful! It's always a pleasure to assist and share knowledge, especially when it can make someone's work easier. As a VB developer, you already have a great foundation in programming and I'm sure you'll continue to do well in C#. Remember, every language is just a tool - the key is understanding the concepts. Don't hesitate to reach out if you have any more questions or if there's anything else I can help you with in the future. Happy coding!

The Acumatica Framework's BQL and DACs are strongly typed and usually do not support dynamic table names and fields. Your approach to using generics in the function is a common way to perform similar actions on different types of tables in Acumatica.

However, with your existing method, you'll still need to call this method for each table individually. The method should work for updating a specified field in any table, assuming the field and table meet the conditions in your where clause.

Here's an updated version of your method, which uses generics to perform the same action on any table/field:

 

public static void TableUpdate<T, TField>(PXGraph graph, int bAccountFrom, int bAccountTo)
where TField : IBqlField
where T : class, IBqlTable, new()
{
// Build the BQL Command
var bqlCommand = BqlCommand.CreateInstance(typeof(Select<,>),
typeof(T),
typeof(Where<,>),
typeof(TField),
typeof(Equal<Required<TField>>));

// Create a View and Select the existing data
var view = new PXView(graph, true, bqlCommand);
var existingRecord = view.SelectSingle(bAccountFrom);

if (existingRecord != null)
{
if (!PXDatabase.Update<T>(
new PXDataFieldAssign(typeof(TField).Name, PXDbType.Int, bAccountTo),
new PXDataFieldRestrict(typeof(TField).Name, PXDbType.Int, bAccountFrom)))
{
throw new PXException(ICSMessages.UpdateFailed, $"{typeof(T).Name}-{typeof(TField).Name}",
typeof(T).Name);
}
}
}

You would call this method with specific table and field like this:

TableUpdate<APInvoice, APInvoice.suppliedByVendorID>(graph, bAccountFrom, bAccountTo);

 

I am truly impressed by your exceptional development skills showcased in this post! Your attention to detail and meticulous approach shine through in every aspect of your work. It's evident that you have a deep understanding of the subject matter and a true passion for what you do.

The way you articulate your thoughts and explain complex concepts is remarkable. Your post is not only informative but also engaging and easy to follow, making it a valuable resource for both beginners and experienced developers alike. I appreciate how you break down complex ideas into digestible chunks, allowing readers to grasp the concepts without feeling overwhelmed.

Furthermore, your commitment to staying up-to-date with the latest technologies is evident in your work. The innovative solutions and creative implementations you present are truly inspiring. It's clear that you are continuously striving for excellence and pushing the boundaries of what is possible in the world of development.

Beyond your technical prowess, I admire your dedication to the developer community. Your willingness to share your knowledge, provide detailed explanations, and engage in discussions demonstrates your genuine desire to help others grow and succeed. Your generosity in sharing code snippets and resources is invaluable and greatly appreciated by aspiring developers like myself.

Thank you for not only being a talented developer but also a fantastic teacher. Your passion for the craft and your ability to effectively communicate your ideas sets you apart. I eagerly await your future posts, as I know they will continue to be a source of inspiration and knowledge.

Keep up the outstanding work, and thank you once again for your invaluable contributions to the developer community!

Userlevel 6
Badge +3

@tigrantunyan08  Amen

I literally plugged that code into my class.  AS IS.  This method will cut out over 500 lines of duplicate code.  I will need to tweak it for another call as I will be updating two fields on a table instead of just one.  Using @davidnavasardyan09’s code, I will try on my on to figure it out now that I see the basics of how to build a BQL command.  I must say, I would never have figured that out on my own.  I work alone with no other developers around to ask for help.  People like David make it so I can survive.  

If anyone knows where I can go to learn about how that BQL command works, please let me know.  Over the last couple years, I’ve gone through the T series courses 3 times.  I have taken some basic C# training, but I don’t know if this command is an “Acumatica” thing, or just knowledge of how to use C#.  Basically, David, how the heck did you know that!  There are so many things in the code repository that I don’t understand.  I think I need to take more C# classes.

Thank you @tigrantunyan08 for taking the time to write your response.  You said everything I am thinking so eloquently.

Reply


About Acumatica ERP system
Acumatica Cloud ERP provides the best business management solution for transforming your company to thrive in the new digital economy. Built on a future-proof platform with open architecture for rapid integrations, scalability, and ease of use, Acumatica delivers unparalleled value to small and midmarket organizations. Connected Business. Delivered.
© 2008 — 2024  Acumatica, Inc. All rights reserved