In one unit I'm running a query which will return one users details from the database. Right now I'm thinking of creating a user object and assigning the results of the query to the different properties, the setting that as a global variable. I wanted to know if there was a way to pass the data between the units without having to use the global variables.
Avoiding global variables is actually a good idea. Also, storing the query result as properties of a (database-independent) object makes sense, because the application might need the information also when the connection is not active.
To avoid a global variable, the easiest way would be to make the object a field of a main form (or datamodule), and use Getter methods to make it (and its fields) read-only. I would also implement the procedure of loading the dataset values into the object properties as a spearate class.
Related
A standard VirtualStringTree in the examples I've seen has a GetText procedure to get at data which is stored in memory via InitNode. It uses a set of Nodes to manage display, ordering etc.
An application which collects and manages some data in its own class (TMyDataClass) but uses a VirtualStringTree just to display it could, however, simply access TMyDataClass's data in GetText without bothering to attach that data to a Node in InitNode (and later freeing it in FreeNode).
I'm trying to understand any downside there is to that. What functionality of VirtualStringTree will I miss if I don't use InitNode and FreeNode? I have nothing against those of course but I just want to understand better.
The TVirtualStringTree is used to handle elements related to display wihtout worrying about what the data actually is.
To allow it to do that, each of the Node records can store additional information to get to the data it needs to know. The Data property. In general you don't want to have multiple copies of your data, so in the Data property of the Node you would store a pointer (reference) to your object from which it can get the data. I understand that the Data property is defined as a record - so you need to define a record to hold your data. (Please note I may be referring to a different version than you are using - check your docs or source code to confirm what you need).
So that would mean you have, for example:
CellText := TMyNodeRecord(Node.Data).AppData.DisplayText;
Where TMyNodeRecord is defined as something like:
type TMyNodeRecord = record
AppData: TMyDataClass;
end;
Where TMyDataClass is your own data object that supplies the text through the DisplayText property (or any other property / metod you like).
As a complete novice programmer I am trying to populate my neo4j DB with data from heterogeneous sources. For this I am trying to use the Neo4jClient C# API. The heterogeneity of my data comes from a custom, continuously evolving DSL/DSML/metamodel that defines the possible types of elements, i.e. models, thus creating classes for each type would not be ideal.
As I understand, my options are the following:
Have a predefined class for each type of element: This way I can easily serialize my objects that is if all properties are primitive types or arrays/lists.
Have a base class (with a Dictionary to hold properties) that I use as an interface between the models that I'm trying to serialize and neo4j. I've seen an example for this at Can Neo4j store a dictionary in a node?, but I don't understand how to use the converter (defined in the answer) to add a node. Also, I don't see how an int-based dictionary would allow me to store Key-Value pairs where the keys (that are strings) would translate to Property names in neo4j.
Generate a custom query dynamically, as seen at https://github.com/Readify/Neo4jClient/wiki/cypher#manual-queries-highly-discouraged. This is not recommended and possibly is not performant.
Ultimately, what I would like to achieve is to avoid the need to define a separate class for every type of element that I have, but still be able to add properties that are defined by types in my metamodel.
I would also be interested to somehow influencing the serializer to ignore non-compatible properties (similarly to XmlIgnore), so that I would not need to create a separate class for each class that has more than just primitive types.
Thanks,
J
There are 2 problems you're trying to solve - the first is how to program the C# part of this, the second is how to store the solution to the first problem.
At some point you'll need to access this data in your C# code - unless you're going fully dynamic you'll need to have some sort of class structure.
Taking your 3 options:
Please have a look at this question: neo4jclient heterogenous data return which I think covers this scenario.
In that answer, the converter does the work for you, you would create, delete etc as before, the converter just handles the IDictionary instance in that case. The IDictionary<int, string> in the answer is an example, you can use whatever you want, you could use IDictionary<string, string> if you wanted, in fact - in that example, all you'd need to do would be changing the IntString property to be an IDictionary<string,string> and it should just work.
Even if you went down the route of using custom queries (which you really shouldn't need to) you will still need to bring back objects as classes. Nothing changes, it just makes your life a lot harder.
In terms of XmlIgnore - have you tried JsonIgnore?
Alternatively - look at the custom converter and get the non-compatible properties into your DB.
I have an aggregated data view in an MVC project which displays the totals per month broken down by audit status. The controller code sets this up using a simple LINQ projection into an anonymous object like this:
From audits In db.Audits
Group By key = audits.DateCreated.Value.Month Into g = Group
Select New With {
.Month = key,
.Assigned = g.Sum(AuditsWithStatus(AuditStatus.Issued)),
.Unassigned = g.Sum(AuditsWithStatus(AuditStatus.Pending)),
.Closed = g.Sum(AuditsWithStatus(AuditStatus.Closed)),
.Cancelled = g.Sum(AuditsWithStatus(AuditStatus.Cancelled))
}
I know this is one of the big advantages of LINQ (using anonymous types), but I don't like losing the strong typing in the view (ie #ModelType SomeStrongType). Is there any general advice on this? Articles, blogs, or other places that deal with the issue and when to use which?
You cannot do anything with anonymous types outside of the scope of your method. You cannot return them to your view for example. In those cases you have to use a known type.
I use anonymous types when I am selecting data that I am then processing in another way. For example, selecting some bespoke data out of 1 source using Linq, and putting to put into another source.
If you are returning aggregate data such as an IEnumerable<IGrouping<TKey, TValue>> and TKey and TValue are anonymous types (you can group by anonymous types if you want); then you would not want to create 2 classes for TKey and TValue, where TKey has an overridden Equals and GetHashCode so you can group by it. And then do nothing more than read some values from it and throw it away, never to be re-used.
TLDR; use them when there is no need to create a known type to store your results. If you need to pass your results to somewhere outside the scope of the method, then you will need a type.
General advice is simple: always create dedicated viewmodel type for your views. In your case it would be pretty simple, containing exactly the properties you have in you anonymous class.
I understand that it seems like an unneeded overhead, but it'll make your code more readable and verifiable.
I am new to db4o.
I have this question in mind:
when the object are retrieved from DAL, maybe it will update in Business layer, then we lost it's original property, so when it comes to updating how can I find which one is the original object in the database to update?
You need to be more precise about "the object". If you modify the object instance's properties, simply storing it again will perform an update:
MyClass someInstance = ObjectContainer.Query<MyClass>().FirstOrDefault();
someInstance.Name = "NewName";
someInstance.PhoneNumber = 12132434;
ObjectContainer.Store(someInstance); // This is the update call
[This is just pseudo-code]
So you don't need to match objects to each other as you would have to when using an RDBMS.
However, you need to make sure you are not using a different instance of ObjectContainer, because a different container will not know these objects are the same instance (since there is no ID field in them).
Your application architecture should help to do this for most workflows, so there should be really only one IObjectContainer around. Only if timespans are really long (e.g. you need to store a reference to the object in a different database and process it somehow) it'd use the UUID. AS you already pointed out, that requires to store the ID somewhere else and hence complexifies your architecture.
If you however intend to create a new object and 'overwrite' the old object, things get somewhat more complicated because of other objects that might refer to it. However, this is a somehwat pathological case and should typically be handled within the domain model itself, e.g. by copying object data from one object to another.
You should load the object via its ID:
objectContainer.get().ext().getByID(id);
or via its UUID:
objectContainer.get().ext().getByUUID(uuId);
See the docs for the latter one. For an explanation see the answer here or the docs here. In short use uuid only for long term referencing.
When getting an object from the DB, should the object's properties also be loaded? There seems to be these approaches.
Create well-formed, fully-loaded objects.
Pro: No need to check if a property has been loaded; it has. Pass it around and don’t worry about parts of the object not being there.
Con: Where do you stop? If an object has an object, and that object has an object, and that object has 40 objects as properties, etc… Do you load the whole DB? Or do you make a decision in the BLL as to what constitutes a well-formed object, and load those properties?
Don’t load any properties that are other objects.
Pro: Quick, no loading unnecessary properties.
Con: Code has to be constantly written to check if properties are populated.
Lazy-loading: only load properties when they are first used.
Pro/Con: Not sure what to say about this approach. It seems intuitively wrong.
Is there another approach? What approach is the best?
And finally, what about properties that can be null? For example, a car may not have a PreviousOwner object. Do you set it to null? An empty PreviousOwner object? Does that property belong in another class then?
There's no easy answer to your question because it depends on what you're trying to achieve.
It looks like you expect a more or less complete object graph to be loaded from the database (i.e. with relationships between multiple object types and the objects themselves stored in the database).
If this is the case, I would look into using the Object Relationship Mapper that's convenient in my language of choice.
As to how much of the object graph is being loaded, the model employed by Apple CoreData's system is objects not yet retrieved are marked as faulty (they call the concept "faulting" - it's described in Limiting the Size of the Object Graph: Faulting. This is a play on the lazy loading concept you described yourself.