I understand that I can retrieve an existing property from my model by using model.getProperty, for example:
Model model;
Property description_property = model.getProperty(NS.dcterms + "description");
But say I don't have the model available but want to create a local model I'm forced to use:
Property descriptionProperty=
ResourceFactory.createProperty(NS.dcterms + "description");
Can someone give a nice explanations of when and why to use model.getProperty vs ResourceFactory.createProperty and its implications.
The two forms are actually pretty much equivalent. The principle difference is that, when you do a model.getXXX to get a property or resource object, that object then contains a pointer back to the model against which it was created. This can be helpful, as in Jena it's really only the model objects that hold state. Java classes such as Resource and Property denote resource and property identities, but the real content is the triples (i.e. Statements) in the model.
To make that concrete, if you do something like:
Resource s = ... ;
Property p = ... ;
RDFNode o = ... ;
p.getModel().addStatement( s, p, o );
that will succeed in your first case (i.e. with Model.getProperty) and fail in the second (i.e. ResourceFactory), since in the second case getModel() will return null. However, whether that's a practical concern in your application is something only you can say. I don't find it to be much of a problem in my code, to be honest.
Incidentally, you may like to know that Jena has a utility called schemagen, which can auto-generate Java source code containing constants corresponding to the classes, properties and individuals in your ontology. It can be clearer and more maintainable than manually creating such constants in your code.
Related
I am trying to understand the best way to work with complex hierarchies of objects that i manipulate based on data on forms in Grails.
I cannot use the command object as my form is dynamic (users can add any number of records). I am told we should parse the params in controller and let services do the transaction activities on the domain objects and thus reduce coupling. Sometimes this doesn't seem straightforward.
I have a few lists of child domain objects in a base domain object that is being 'updated' which means the list could have grown or reduced, meaning some domain tuples will need to be added/removed, how do i pass that information from controller to service without making a function with 8 parameters? If anyone has any strategies you've used, please share. I am sure this is not uncommon but I haven't seen any discussions on such a question.
e.g.
class DomainA {
List<DomainB> bList
List<DomainC> cList
DomainD domD
}
class DomainD {
List<DomainE> elist
}
How about relying on ajax. You might save classD and then class A, or use a command object to save both. Then with the Id´s of these two classes you might add everything else you need using ajax.
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 know how to do it using the OntModel, but the problem with this constructor is that I am getting also the classes from the imported ontologies, and I only want to get the classes and subclasses from the BaseModel.
If I use the method listSubjects() I also get the properties and I dont want them.
Thank you.
No matter what, if you only want results from the base model, you'll have to get the base model from the OntModel with OntModel.getBaseModel. If the base model also happens to be an OntModel, you could simply cast it:
OntModel model = ...;
OntModel base = (OntModel) model.getBaseModel();
If the other classes are coming from submodels (which are not exactly the same as ontologies imported by owl:imports, though ontologies imported with owl:imports will be submodels of the OntModel), you could just create a new OntModel with the same base model, but none of the other submodels:
OntModel model = ...;
OntModel wrappedBase
= ModelFactory.createOntologyModel( model.getSpecification(),
model.getBaseModel() );
and then use wrappedBase to list the classes and subclasses you're interested in. If you really don't want a second OntModel, then you could ask for the statements in the base model that represent the things you're interested in, but this will require knowledge of how the ontology language represents classes. OWL models are probably the most common, so you could do something like:
OntModel model = ...;
Model base = model.getBaseModel();
... = base.listStatements( null, RDF.type, OWL.Class );
... = base.listStatements( null, RDFS.subClassOf, null );
and work with those statements. The first two approaches will be easier, of course.
In MVC if you want to create an editor for a property or a display for you property you do something like that:
#Html.EditorFor(m=> m.MyModelsProperty);
#Html.DisplayFor(m=> m.MyModlesProperty);
Why do we have to pass a delegate why can't we just pass the model's property directlly? e.g.:
#html.EditorFor(Model.MyModlesProperty);
The reason for this is because of Metadata. You know, all the attributes you could put on your model, like [Required], [DisplayName], [DisplayFormat], ... All those attributes are extracted from the lambda expression. If you just passed a value then the helper wouldn't have been able to extract any metadata from it. It's just a dummy value.
The lambda expression allows to analyze the property on your model and read the metadata from it. Then the helper gets intelligent and based on the properties you have specified will act differently.
So by using a lambda expression the helper is able to do a lot more things than just displaying some value. It is able to format this value, it is able to validate this value, ...
I'd like to add, that besides the Metadata and making the Html helper strongly typed to the Model type, there's another reason:
Expressions allow you to know the name of the property without you hard coding strings into your project. If you check the HTML that's produced by MVC, you'll see that your input fields are named "ModelType_PropertyName", which then allows the Model Binder to create complex types that are passed to your Controller Actions like such:
public ActionResult Foo(MyModel model) { ... }
Another reason would be Linq to SQL. Expression Trees are the magic necessary to convert your Lambdas to SQL queries. So if you were to do something like:
Html.DisplayFor(p => p.Addresses.Where(j => j.Country == "USA"))
and your DbContext is still open, it would execute the query.
UPDATE
Stroked out a mistake. You learn something new every day.
The first example provides a strongly-typed parameter. It forces you to choose a property from the model. Where the second is more loosely-typed, you could put anything in it, even something that isn't valid property of the model.
Edit:
Surprisingly, I couldn't find a good example/definition of strong vs loose typing, so I'll just give a short example regarding this.
If the signature was #html.EditorFor(string propertyName); then I could make a typo when typing in the name and it would not be caught until run-time. Even worse, if the properties on the model changed, it would NOT throw a compiler error and would again not be detected until run-time. Which may waste a lot of time debugging the issue.
On the other hand with a lambada, if the model's properties changed you would get a compiler error and you would have to fix it if you wanted to compile your program. Compile-time checking is always preferred over run-time checking. This removes the chance of human error or oversight.
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.