Author Topic: Best way to access content from C#  (Read 3701 times)

eahlers

  • EA Novice
  • *
  • Posts: 7
  • Karma: +0/-0
    • View Profile
Best way to access content from C#
« on: August 28, 2024, 04:08:28 pm »
Hello,

this is a general question more about increasing my knowledge/understanding than really solving a problem.

I have a C# program where I access EAs object model (https://sparxsystems.com/enterprise_architect_user_guide/14.0/automation/theautomationinterface.html) via COM objects. Normally I first iterate through all packages (recursively) to get all the existing wanted elements into my data structure. For example elements can be stored in my C# program as
Code: [Select]
public class EaElement(EA.Element e, string parentFullName)
{
    public readonly EA.Element E = e;
    public readonly string Name = e.Name;
    public readonly string FullName = parentFullName + "/" + e.Name;
}
So later I can use my C# internal data to find the related elements.

On the other hand I could also store only the ID of the element (not the object reference) and query the real element always from the repository.

With my currently used object storing I have a somewhat bigger amount of COM objects in my data. Could this be a problem? I'm not 100% sure about those object lifetimes and whether there is a limit in the number.

Sometimes I got a COM exception when try to use such an object. Or even not all objects seems to be returned from my first "object gathering". But that's quite seldom and might be more that I created some garbage when developing my C# program and stop "somewhere in the middle". This is more a feeling than a fact.

EA documentation talks always about tables. And I know that internally there is a (SQL?) database that holds the data in tables (as normal SQL databases do). Would it be better or even more performant to get this table content directly? I wouldn't know how. But at least in the beginning, where I first gather the information what is all existing in my model, this might be a better way.

I'm pretty sure there are many people outside that have more knowledge about this issue than i. May be they can share some info that increases my knowledge  ::)

qwerty

  • EA Guru
  • *****
  • Posts: 13584
  • Karma: +396/-301
  • I'm no guru at all
    • View Profile
Re: Best way to access content from C#
« Reply #1 on: August 28, 2024, 04:58:02 pm »
The EA API offers a COM representation of the database it internally uses to persist the model. This is a SQL DB xou can configure. EAP is just M$Access. Others SQL DBs are supported but you must configure them (use one of the Sparx' providede schemes. For good and worse you can bypass the API to work directly on the DB.

q.

eahlers

  • EA Novice
  • *
  • Posts: 7
  • Karma: +0/-0
    • View Profile
Re: Best way to access content from C#
« Reply #2 on: August 28, 2024, 06:19:18 pm »
I know that it's possible to connect an own C# application to an external SQL database.So I could create own SQL queries in my application.
Do you know about an example how to connect my C# application to the EA internal DB?

Not sure, if I would really use it. But it would be at least interesting to try it once. May be there are reasons to use it later.

qwerty

  • EA Guru
  • *****
  • Posts: 13584
  • Karma: +396/-301
  • I'm no guru at all
    • View Profile
Re: Best way to access content from C#
« Reply #3 on: August 28, 2024, 07:09:28 pm »
You might be interested to look into my Inside and Scripting book. Will try to dig out the way to access the document.

q.

qwerty

  • EA Guru
  • *****
  • Posts: 13584
  • Karma: +396/-301
  • I'm no guru at all
    • View Profile
Re: Best way to access content from C#
« Reply #4 on: August 28, 2024, 08:01:41 pm »
So here it is: First you need to get the element that contains the linked document. Thereof you need its guid and with that you can retrieve the packed document from the document table. In short:

Code: [Select]
SELECT bincontent from t_document inner join t_object on t_object.ea_guid = t_document.ElementID where t_object.Object_ID = <element-id>
Just replace <element-id> and you have the packed content at hand. You noe need to unzip that. It contains a single file names str.dat which holds the data you're after.

You can issue the above either native or using the API's repository.execute (an undocumented feature). That yields a XML result.

As said: it's tricky. But with a bit of patience you get what you want.

q.

eahlers

  • EA Novice
  • *
  • Posts: 7
  • Karma: +0/-0
    • View Profile
Re: Best way to access content from C#
« Reply #5 on: August 28, 2024, 09:40:16 pm »
To do this I first have to connect from my C# application to the data base. My question is mainly how can I do this?

qwerty

  • EA Guru
  • *****
  • Posts: 13584
  • Karma: +396/-301
  • I'm no guru at all
    • View Profile
Re: Best way to access content from C#
« Reply #6 on: August 28, 2024, 11:13:09 pm »
As said: use repository.execute. If you want native access (extra dangerous) use a fitting driver. ODBC should provide you with the needed tool.

q.

Geert Bellekens

  • EA Guru
  • *****
  • Posts: 13387
  • Karma: +566/-33
  • Make EA work for YOU!
    • View Profile
    • Enterprise Architect Consultant and Value Added Reseller
Re: Best way to access content from C#
« Reply #7 on: August 29, 2024, 05:56:14 pm »
The way I do it is to always use the API, unless I don't have any other choice.

But only load the elements you need, when you need them. If you load them too soon, they might already have changed, or worse deleted, when you deal with them.

There are a few tips however to make the process a bit smoother.

- iterating collections is super slow. Avoid that at all costs. If you need, say all requirements with status "Active", then an SQL query to get those requirements. There is Repository.GetElementSet, and Repository.SQLQuery which you can use to get either the complete set of elements, or a set of ID's that you can use to load the elements (or diagrams, or attributes, or...)

- If you are not sure the API element you have in memory still represents the latest state, then reload it by getting it again based on it's id.

- Use the undocumented Repository.Execute only when there is no other option. You can pass an SQL update query to that method and it will get executed. There is no feedback.

All of my C# addins are open source and available on github: https://github.com/GeertBellekens

Geert