Retrieving data from Notes using the COM API - c#

I'm trying to open a view from a Lotus Notes database using the NotesSQL ODBC driver and the COM API. When I use Access to 'link to external data', using notesSQL over 380 'tables' are listed.
The following C# code was written with the COM API to list out the views: only 230 objects are returned. It appears that actual tables that contain the data are excluded from the Views list.
var _someDatabase = _lotesNotesSession.GetDatabase("MainServer/Server/Company/US", #"Groups\Location\someNotesDatabase", false);
var _views = _someDatabase.Views;
foreach (var view in _views)
Console.WriteLine(view.Name);
What is the proper way to connect to the tables that actually contain the data?

Revised based on your comments.
Okay... So you are not using NotesSQL. You are using the Notes COM API. If you want to get a list of all the Views in a Notes Database, you use the _someDatabase.Views property, as you have done. But to read data out of a Notes database, you need to read NotesDocument objects, which contain NotesItem objects.
There are a number of ways to read NotesDocument objects. E.g.,
Using the NotesDatabase.AllDocuments property which gives you a NotesDocumentCollection object containing all the NotesDocuments
Using the NotesDatabase.Search method, which gives you a NotesDocumentCollection object containing only the NotesDocument objects that meet a search criterion.
Looping through the collection of NotesDocuments associated with a particular view.
I'll briefly cover the last option, because it will underscore a point that I want to make.
Views contain NotesDocument objects in what we call their collection. The same is true of Folders. You've got the views (as an array of NotesView objects) from your call to _someDatabase.Views, so for any of those views, you can do something like this:
thisDoc = view.GetFirstDocument
while (thisDoc != null)
{
processNotesDocument(thisDoc)
thisDoc = view.GetNextDocument
}
And then you could write a processNotesDocument function that uses Notes COM API calls to read the data (i.e. the NotesItem objects) from the NotesDocument. You can look at the documentation for the NotesDocument class to figure out how to do that.
The thing is, before you can go and do that, you'd have to answer the question: which view (or views) do I want to do this in? Or you'd have to choose one of the other methods that I listed above for accessing the NotesDocument objects.
I don't mean to be disrespectful, but I think you're going to need to know a bit more about the data that you are dealing with, and about Lotus Notes database design, before you can address that. I'm infering that from the fact that your question doesn't show that you even know that the basic unit of information in Lotus Notes is called a "document", and Notes programming has a big API and it's just not something that one can usually navigate through without some idea of where you're going in the first place.
Here's a link that will take you to the reference info for the NotesDocument class. It should also bring up navigation for the documenation for all the other classes in the API. But what I think you really need is a tutorial on the basic concepts of Lotus Notes programming, and unfortunately all the good stuff is old and not oriented toward C#. The good news is that the classes and the concepts are all pretty much the same for the API in C# as they are in the LotusScript language that is native to Notes, and not too different from the classes and concepts in in the API for Java -- and even the fairly old stuff is still going to be good on the basics that you need. Here's a link to another StackOverflow question that can help point you in the direction of some material that can help you.
=================================================================================
Original answer from this point on...
First: Is the C# code running under the same Notes ID that Access is? If not, then security restrictions within the Notes database design might be responsible for the different results. Or at least partially responsible.
Second: I think you know this (because you used quotes around 'tables'), but there are no tables. The NotesSQL driver only makes it look like there are tables, and it uses both Views and Forms for that. A Notes database with 160 Forms would be a bit unusual, but not entirely unheard of. That might be what you are seeing. Bear in mind, though, that NotesSQL queries against Views will be more efficient than queries against Forms, becuase the former go against the indexes that are pre-built on the server, whereas the latter have to do a search through the entire database. If you need to query for fields that are not included in any existing View, then you can certainly use a query against a Form. You can get the list of Forms via _localDatabase.Forms. But the better way would be to use Domino Designer to add the Views that you need, and then do your NotesSQL query against the Views.
Third: But I'm a little confused by why you wrote the above code, because it's not using NotesSQL. It's using the Notes COM API (presumably through the interop DLL) since this is C#. But since you're doing that, then why bother with NotesSQL? You're already using an API that is much better suited for doing operations on Notes/Domino data, and might very well give you a way to get your data more efficiently than NotesSQL can -- without having to add any new Views to the database, though that could depend on your understanding of the existing Views, data relationships, etc.
Finally: Unrelated to your actual question, but just some friendly advice: you should really change the name of your variable _localDatabase. Anyone with Notes/Domino experience would likely interpret "local" to refer to a database that is being accessed without going through a Domino server -- which is what I thought at first. But with a closer look at your code, I see that you are actually opening a database on a server named MainServer/Server/Company/US.

Related

Using a Data Access Layer in an OOP C# application using SQL

I have come from an environment where I was taught to use objects and employ OOP techniques where possible and I guess it has guided me down a particular road and influenced my product designs for quite some time.
Typically my data access layer will have a number of classes which map onto database tables, so if I need to display a list of Companies, I will have a 'Company' object and a database table called 'company'. The company object knows how to instantiate itself from a DataRow from the database read using a 'SELECT * FROM company WHERE id = x' type query. So when-ever I display a companies list I will populate a list of company objects and display them. If I need to display attributes of the company I already have the data loaded.
It has been mentioned that 'select *' is frowned on and my object approach can be inefficient, but I am having issues identifying another way of working with a database table and objects which would work if you only read specific fields - the object just wouldn't be populated.
Yes I could change the list to directly query just the required fields from the database and display them but that means my UI code would need to be more closely linked to the data access code - I personally like the degree of separation of having the object separating the layers.
Always willing to learn though - I work on my own so don't always get up to speed with the latest technologies or methodologies so any comments welcome.
I don't think I can show you a definitive solution to that, but I'll try pointing you on the right direction (since it's more of a theoretical question).
Depending on the design pattern you follow on your application, you could decouple the data access layer from the UI and still follow this rule of not fetching all columns when they are not necessary. I mean, chosing the right design pattern for an application can bring you this sort of easyness.
For example, maybe you could interpret the less detailed version of an object as an object itself (which honestly I don't think it would be a good approach).
Also, I'll comment that the very popular rails ORM ActiveRecord only fetches from DB when the data is used. Maybe you could use a similar logic to track not only when but which columns will be used so you could limit the query.

Serializing complex EF model over JSON

I have done a lot of searching and experimenting and have been unable to find a workable resolution to this problem.
Environment/Tools
Visual Studio 2013
C#
Three tier web application:
Database tier: SQL Server 2012
Middle tier: Entity Framework 6.* using Database First, Web API 2.*
Presentation tier: MVC 5 w/Razor, Bootstrap, jQuery, etc.
Background
I am building a web application for a client that requires a strict three-tier architecture. Specifically, the presentation layer must perform all data access through a web service. The presentation layer cannot access a database directly. The application allows a small group of paid staff members to manage people, waiting lists, and the resources they are waiting for. Based on the requirements the data model/database design is entirely centered around the people (User table).
Problem
When the presentation layer requests something, say a Resource, it is related to at least one User, which in turn is related to some other table, say Roles, which are related to many more Users, which are related to many more Roles and other things. The point being that, when I query for just about anything EF wants to bring in almost the entire database.
Normally this would be okay because of EF's default lazy-load behavior, but when serializing just about any object to JSON for returning to the presentation layer, the Newtonsoft.Json serializer hangs for a long time then blows a stack error.
What I Have Tried
Here is what I have attempted so far:
Set Newtonsoft's JSON serialier ReferenceLoopHandling setting to Ignore. No luck. This is not cyclic graph issue, it is just the sheer volume of data that gets brought in (there are over 20,000 Users).
Clear/reset unneeded collections and set reference properties to null. This showed some promise, but I could not get around Entity Framework's desire to track everything.
Just setting nav properties to null/clear causes those changes to be saved back to the database on the next .SaveChanges() (NOTE: This is an assumption here, but seemed pretty sound. If anyone knows different, please speak up).
Detaching the entities causes EF to automatically clear ALL collections and set ALL reference properties to null, whether I wanted it to or not.
Using .AsNotTracking() on everything threw some exception about not allowing non-tracked entities to have navigation properties (I don't recall the exact details).
Use AutoMapper to make copies of the object graph, only including related objects I specify. This approach is basically working, but in the process of (I believe) performing the auto-mapping, all of the navigation properties are accessed, causing EF to query and resolve them. In one case this leads to almost 300,000 database calls during a single request to the web service.
What I am Looking For
In short, has anyone had to tackle this problem before and come up with a working and performant solution?
Lacking that, any pointers for at least where to look for how to handle this would be greatly appreciated.
Additional Note: It occurred to me as I wrote this that I could possibly combine the second and third items above. In other words, set/clear nav properties, then automap the graph to new objects, then detach everything so it won't get saved (or perhaps wrap it in a transaction and roll it back at the end). However, if there is a more elegant solution I would rather use that.
Thanks,
Dave
It is true that doing what you are asking for is very difficult and it's an architectural trap I see a lot of projects get stuck in.
Even if this problem were solveable, you'd basically end up just having a data layer which just wraps the database and destroys performance because you can't leverage SQL properly.
Instead, consider building your data access service in such a way that it returns meaningful objects containing meaningful data; that is, only the data required to perform a specific task outlined in the requirements documentation. It is true that an post is related to an account, which has many achievements, etc, etc. But usually all I want is the text and the name of the poster. And I don't want it for one post. I want it for each post in a page. Instead, write data services and methods which do things which are relevant to your application.
To clarify, it's the difference between returning a Page object containing a list of Posts which contain only a poster name and message and returning entire EF objects containing large amounts of irrelevant data such as IDs, auditing data such as creation time.
Consider the Twitter API. If it were implemented as above, performance would be abysmal with the amount of traffic Twitter gets. And most of the information returned (costing CPU time, disk activity, DB connections as they're held open longer, network bandwidth) would be completely irrelevant to what developers want to do.
Instead, the API exposes what would be useful to a developer looking to make a Twitter app. Get me the posts by this user. Get me the bio for this user. This is probably implemented as very nicely tuned SQL queries for someone as big as Twitter, but for a smaller client, EF is great as long as you don't attempt to defeat its performance features.
This additionally makes testing much easier as the smaller, more relevant data objects are far easier to mock.
For three tier applications, especially if you are going to expose your entities "raw" in services, I would recommend that you disable Lazy Load and Proxy generation in EF. Your alternative would be to use DTO's instead of entities, so that the web services are returning a model object tailored to the service instead of the entity (as suggested by jameswilddev)
Either way will work, and has a variety of trade-offs.
If you are using EF in a multi-tier environment, I would highly recommend Julia Lerman's DbContext book (I have no affiliation): http://www.amazon.com/Programming-Entity-Framework-Julia-Lerman-ebook/dp/B007ECU7IC
There is a chapter in the book dedicated to working with DbContext in multi-tier environments (you will see the same recommendations about Lazy Load and Proxy). It also talks about how to manage inserts and updates in a multi-tier environment.
i had such a project which was the stressful one .... and also i needed to load large amount of data and process them from different angles and pass it to complex dashboard for charts and tables.
my optimization was :
1-instead of using ef to load data i called old-school stored procedure (and for more optimization grouping stuff to reduce table as much as possible for charts. eg query returns a table that multiple charts datasets can be extracted from it)
2-more important ,instead of Newtonsoft's JSON i used fastJSON which performance was mentionable( it is really fast but not compatible with complex object. simple example may be view models that have list of models inside and may so on and on or )
better to read pros and cons of fastJSON before
https://www.codeproject.com/Articles/159450/fastJSON
3-in relational database design who is The prime suspect of this problem it might be good to create those tables which have raw data to process in (most probably for analytics) denormalized schema which save performance on querying data.
also be ware of using model class from EF designer from database for reading or selecting data especially when u want serialize it(some times i think separating same schema model to two section of identical classes/models for writing and reading data in such a way that the write models has benefit of virtual collections came from foreign key and read models ignore it...i am not sure for this).
NOTE: in case of very very huge data its better go deeper and set up in-memory table OLTP for the certain table contains facts or raw data how ever in that case your table acts as none relational table like noSQL.
NOTE: for example in mssql you can use benefits of sqlCLR which let you write scripts in c#,vb..etc and call them by t-sql in other words handle data processing from database level.
4-for interactive view which needs load data i think its better to consider which information might be processed in server side and which ones can be handled by client side(some times its better to query data from client-side ... how ever you should consider that those data in client side can be accessed by user) how ever it is situation-wise.
5-in case of large raw data table in view using datatables.min.js is a good idea and also every one suggest using serverside-paging on tables.
6- in case of importing and exporting data from big files oledb is a best choice i think.
how ever still i doubt them to be exact solutions. if any body have practical solutions please mention it ;) .
I have fiddled with a similar problem using EF model first, and found the following solution satisfying for "One to Many" relations:
Include "Foreign key properties" in the sub-entities and use this for later look-up.
Define the get/set modifiers of any "Navigation Properties" (sub-collections) in your EF entity to private.
This will give you an object not exposing the sub-collections, and you will only get the main properties serialized. This workaround will require some restructuring of your LINQ queries, asking directly from your table of SubItems with the foreign key property as your filtering option like this:
var myFitnessClubs = context.FitnessClubs
?.Where(f => f.FitnessClubChainID == myFitnessClubChain.ID);
Note 1:
You may off-cause choose to implement this solution partly, hence only affecting the sub-collections that you strongly do not want to serialize.
Note 2:
For "Many to Many" relations, at least one of the entities needs to have a public representation of the collection. Since the relation cannot be retrieved using a single ID property.

Database handling in applications

This is a bit of difficult question to ask but any feedback at all is welcome.
Ill start by the background, I am a university student studying software engineering last year we covered c# and I got myself a job working in a software house coding prototype software in c# (their main language is c++ using QT) after producing the prototype it was given to some clients which have all passed back positive feedback.
Now I am looking at the app and thinking well I could use this as a showcase with my CV esp as the clients who used the software have said that they will sign something to reference it.
So if I am going to do that then I had better get it right and do it to the best I possibly can. so I have started to look at it and think where I can improve it and one of the ways in which I think that I can is the way it handles the database connections and the data along with it.
the app itself runs along side a MySQL server and there is 6 different schemas which it gets its data from.
I have written a class (called it databaseHandler) which has the mysqlconnection in it ( one question was about if the connection should remain open the whole time the app is running, or open it fire a query then close it etc) inside this class I have written a method which takes some arguments and creates its query string which it then does the whole mysqlDataReader = cmd.executeReader(), this then returns the reader back to where ever it was called from.
After speaking to a friend he mentioned it might be nice if the method returned the raw data and not the reader, therefore keeping all the database "stuff" away from the main app.
After playing around I managed to find a couple of tutorials on putting the reader data into arrays and arraylists and passing then back, also had a go at passing back an array list of hashtables - these methods obv mean that the dev must know the column names in order to find the correct data.
then I stumbled across a page which went on about creating a Class which had the attributes of the column names and created a list which you could pull your data from:
http://zensoftware.org/archives/248 is the link
so this made me think, in order to use this method, would I need to create 6 classes with the attributes of the columns of my tables ( a couple of tables has up to 10-15 columns)? or is there a better way for me to handle my data?
I am not really clued up on these things but if pointed in the right direction I am a very fast learner :)
Again I thank you for any input what so ever.
Vade
You have a lot of ideas that are very close but are pretty common problems, but good that you are actively thinking about how to handle them!
On the question about leaving the connection open for the whole program or only having it open during the actual query time. The common (and proper) way to do this is only have the connection open as much as you need it, so
MySqlConnection cn = new MySqlConnection(yourConnectionString);
//Execute your queries
cn.close();
This is better since you don't risk leaving open connections, or having transaction issues typing up databases and resources.
With the having just the data returned and not the actual datareader this is a good idea but by just returning the data as an ArrayList or whatever you are kind of losing the structure of the data a little.
A good way to do this would be to either have your class just take the datareader to populate it's data OR have the Data Layer just return an instance of your class after reading the data.
I believe that it would be an excellent approach if your data access class returned a custom class populated with data from the database. That would be object-oriented. Instead of, say, returning a DataSet or an array containing customer information, you would create a Customer class with properties. Then, when you retrieve the data from the database, you populate an instance of the Customer class with the data, and return it to the calling code.
A lot of the newer Microsoft technologies are focusing on making this task easier. Quite often, there are many more than 6 classes needed, and writing all that code can seem like drudgery. I would suggest that, if you are interested in learning about those newer approaches, and possibly adapting them to your own code, you can check out Linq to SQL and Entity Framework.
one question was about if the connection should remain open the whole
time the app is running, or open it fire a query then close it etc
You want to keep the connection open as little as possible. Therefore you should open on each data request and close it as soon as you are done. You should also dispose it but if your database stuff is inside a C# using statement that happens automatically.
As far as the larger question on how to return the data to your application you are on the right track. You typically want to hide the raw database from the rest of your application and mapping the raw data to other intermediate classes is the correct thing to do.
Now, how you do this mapping is a very large topic. Ideally you don't want to create classes that map one to one your tables/columns but rather provide your app a more app-friendly representation of the data (e.g. business objects rather than database tables.) For example, if your employee data is split in to or three tables for normalization purposes you can hide this complexity and present the information as a single Employee class that binds the data from the other tables together.
Abstracting away your data access code using objects is known as Object/Relational mapping. It's actually a much more complex task than it appears at first sight. There are several libraries, even in the framework itself, that already do very well what you're trying to implement.
If your needs are very simple, look into typed DataSets. They let you create the table classes in a designer and also generate objects that will do the loading and saving for you (given certain limitations)
If your needs are less simple, but still pretty simple, I recommend you take a look at Linq To SQL to see if it covers your needs, as it does table-class mapping in a very straightforward way and uses a more modern usage pattern than DataSets.
There are also more complex ORMs that allow you to define more complex mappings, like Entity Framework or nHibernate, but very often their complexity is not necessary.
Details like connection lifetime will then depend on your specific needs. Sometimes it's best to keep the connection open, if you have a lot of queries caused by user interaction, like is usually the case with a desktop app. Other times it's best to keep them as short as possible to avoid congestion, like the case of web apps.
Whichever technology you choose will likely end up guiding you onto a good set of practices for it, and the best you can do is try things out and see which works best for you.

Methods for storing searchable data in C#

In a desktop application, I need to store a 'database' of patient names with simple information, which can later be searched through. I'd expect on average around 1,000 patients total. Each patient will have to be linked to test results as well, although these can/will be stored seperately from the patients themselves.
Is a database the best solution for this, or overkill? In general, we'll only be searching based on a patient's first/last name, or ID numbers. All data will be stored with the application, and not shared outside of it.
Any suggestions on the best method for keeping all such data organized? The method for storing the separate test data is what seems to stump me when not using databases, while keeping it linked to the patient.
Off the top of my head, given a List<Patient>, I can imagine several LINQ commands to make searching a breeze, although with a list of 1,000 - 10,000 patients, I'm unsure if there's any performance concerns.
Use a database. Mainly because what you expect and what you get (especially over the long term) tend be two totally different things.
This is completely unrelated to your question on a technical level, but are you doing this for a company in the United States? What kind of patient data are you storing?
Have you looked into HIPAA requirements and checked to see if you're a covered entity? Be sure that you're complying with all legal regulations and requirements!
I think 1000 is to much to try to store in XML. I'd go with a simple db type, like access or Sqlite. Yes, as a matter of fact, I'd probably use Sqlite. Sql Server Express is probably overkill for it. http://sqlite.phxsoftware.com/ is the .net provider.
I would recommend a database. You can use SQL Server Express for something like that. Trying to use XML or something similar would probably get out of hand with that many rows.
For smaller databases/apps like this I've yet to notice any performance hits from using LINQ to SQL or Entity Framework.
I would use SQL Server Express because it has the best tool support (IDE integration) from Microsoft. I don't see any reason to consider it overkill.
Here's an article on how to embed it directly in your application (no separate installation needed).
If you had read-only files provided by another party in some kind of standard format which were meant to be used by the application, then I would consider simply indexing them according to your use cases and running your searches and UI against that. But that's still some customized work.
Relational databases are great for storing data in tables, and for representing the relationships between tables. Typically there are also good tools for getting the data in and out.
There are other systems you could use to store your data, but none which would so quickly be mapped to your input (you didn't mention how your data would get into this system) and then be queryable against with least effort.
Now, which database to choose...
Use Database...but maybe just SQLite, instead of a fully fledged database like MS SQL (Express).

How do I correctly separate the database operations from the gui/logic in c# when working with datasources?

Im having a really hard time figuring out how to specify a good search term for my problem: separation of gui and database interaction in visual studio 2008 using Linq to sql.
According to my teacher in a c# class im taking it's not correct to let the GUI be dependant on a specific way of getting data.
The way my project is currently set up is that we have a mssql database where everything is stored.
The solution is split into 4 seperate projects. UserGUI, AdminGUI, Logic and Db.
Now using linq to populate listboxes and similar things I use something like:
From the windows form in the project UserGUI:
//The activeReservationBindingSource has Db.ActiveReservation as it's value
private void refreshReservation() {
activeReservationBindingSource.DataSource = logic.getActiveReservationsQry();
}
To the Logic project:
public IQueryable getActiveReservationsQry() {
return dbOperations.getActiveReservationsQry(this.currentMemberId);
}
To the database project:
public IQueryable getActiveReservationsQry(int memberId) {
var qry =
from active in db.ActiveReservations
where active.memberId == memberId
orderby active.reservationId
select active;
return qry;
}
This makes sense to me seing as I can send items from listboxes all the way to the database project and there easily update/insert things into the mssql database. The problem is that it would be pretty hard to merge over from a mssql database to lets say an access version.
What should I be reading up on to understand how to do this correctly? Is creating my own classes with the same values as the ones visual studio generates for me when I create the dbml file a way to go? Should I then in the logic project populate for example List that I pass to the GUI? To me it seams like "double work" but perhaps it's the correct way to go?
Be adviced that we have not read anything about design patterns or business logic which seems to be a pretty big subject which im looking forward to exploring outside the frame of the course at a later time.
I was also thinking that IQueryable inherits from IEnumerable and perhaps that was the way to go but I have failed to find any information that made sense to me on how to actually accomplish this.
The GUI also knows about the datasources which I think is a bad thing but can't figure out how to get rid of.
Please understand that I tried to figure this out with my teacher for half an hour today at the only tutoring available for this project and then spent most of the day trying to find similar answers on google, SO and from classmates without any result.
There's a post here that I answered where the question was a bit similar to yours. I think it worth to take a look.
Regards
One keyword to read up on: Model-View-Controller. That's kind of the idea you're after. Your "View" is the GUI. The "Model" is the data layer, and the Controller is the code that takes data from the DB and hands it to the GUI (and vice-versa.)
Check out the repository pattern. There are several implementations you can find by googling "Linq repository."
you may want to check out the MVC Storefront series here: http://www.asp.net/learn/mvc-videos/#MVCStorefrontStarterKit. In the series, Rob Conery builds a Linq IQueryable repository that returns custom made objects instead of the linq objects.
May be you can take a look at Data Abstract
According to my teacher in a c# class im taking it's not correct to let the GUI be dependant on a specific way of getting data.
Honestly your teacher is an idiot. This is one of the stupidest statements, from a database perspective, I've ever read. Of course you want to be dependant on a specific way of getting data if that is the most performant way to get the data (which is almost always database specific and means not using LINQ to SQL for complex queries but that is another who issue). Users care about performance not database independence.
Very few real world applications truly need to be database independant. Yes a few kinds of box software sold commercially are (although I think this is usually a mistake and one reason why every commercial product I've ever used is badly designed and horribly slow).
And since every database implements SQl differntly, even using ANSII sql is not completely database independant. Access in particular is no where near close to the ANSII standard. There is no way to write code which will work correctly on every single possible database.

Categories

Resources