How to retrieve data from umbraco by route to model? - umbraco

i got the node
var l= UmbracoContext.Current.ContentCache.GetByRoute("1080/companies")
the node is list of doctype company
how to serlize the node to list of comany class that in
all.generated.cs ??

It should already be of type Company. You should be able to just cast it to your model type, e.g something like:
var l = UmbracoContext.Current.ContentCache.GetByRoute("1080/companies") as Company;
Or
var l = (Company)UmbracoContext.Current.ContentCache.GetByRoute("1080/companies");
Assuming that the generated class is called Company.

Related

Adding a join to a JPA CriteriaQuery

I have a CriteriaQuery on my FlowStep object.
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<FlowStep> cbQuery = cb.createQuery(FlowStep.class);
Root<FlowStep> flowStep = cbQuery.from(FlowStep.class);
List<Predicate> predicates = new ArrayList<>();
Then I add many predicates depending on what I want to filter.
// add all the conditions to query
cbQuery.select(flowStep).where(predicates.toArray(new Predicate[0]));
I even add sorting stuff.
cbQuery.orderBy(orders);
Query query = em.createQuery(cbQuery);
List<FlowStep> resultList = query.getResultList();
But I need to add a join like this:
select * from flowstep fs join flowinstance fi on fi.id = fs.flowinstanceid and fi.domainid = 'Test'
so I only want to return the flow steps matching the criteria AND which are in the Test domain, and domain information is in table flowinstance.
How do you add join to a CriteriaQuery?
I saw something like
Join<FlowStep, UUID> flowStepFlowInstanceJoin = flowStep.join(FlowInstance_.id);
but then I need to add the condition on the domain being equal to a value.
Is it possible to use a join like the above on a JPQL criteria query?
The initial answer was to add this before the Predicate list:
Join<FlowStep, FlowInstance> flowStepFlowInstanceJoin = flowStep.join("id", JoinType.LEFT);
flowStepFlowInstanceJoin.on(cb.equal(flowStepFlowInstanceJoin.get("domainid"), domain));
FlowStep has a flowinstanceid column and field, and flowinstance has an id field.
This compiles but does not work.
I get an error "Cannot join to attribute of basic type".
So there needs to be a one-to-many relationship between FlowStep and FlowInstance?
A FlowInstance has many flow steps so maybe
#Column(name = flowinstanceid)
private UUID flowInstanceId;
in FlowStep class needs to be changed to a JoinColumn? And add a OneToMany or ManyToOne relationship to make the above JOIN possible?
The solution was suggested by CriteriaBuilder join two tables with a custom condition and JPA many-to-one relation - need to save only Id.
In class FlowStep, we need to add the FlowInstance object and a ManyToOne annotation:
#JoinColumn(name = FLOW_INSTANCE_ID, insertable = false, updatable = false)
#ManyToOne(targetEntity = FlowInstance.class, fetch = FetchType.EAGER)
#JsonIgnore
private FlowInstance flowInstance;
Note the class already had a field for the flow instance id of type UUID, but a field of class FlowInstance is necessary, it seems, for the ManyToOne relationship.
Then when building the JPA query:
Join<FlowStep, FlowInstance> flowStepFlowInstanceJoin = flowStep.join("flowInstance", JoinType.INNER);
flowStepFlowInstanceJoin.on(cb.equal(flowStepFlowInstanceJoin.get("domainId"), domain));
This goes below the
Root<FlowStep> flowStep = cbQuery.from(FlowStep.class);
line.
This makes it work.
It's very important that the join is of type INNER so that it only returns the steps having the wanted domain. LEFT would return steps with a non-wanted domain, and RIGHT would return as many null rows as steps having the wanted domain.

Getting only what is needed with Entity Framework

With a plain connection to SQL Server, you can specify what columns to return in a simple SELECT statement.
With EF:
Dim who = context.Doctors.Find(3) ' Primary key is an integer
The above returns all data that entity has... BUT... I would only like to do what you can with SQL and get only what I need.
Doing this:
Dim who= (From d In contect.Doctors
Where d.Regeneration = 3
Select New Doctor With {.Actor = d.Actor}).Single
Gives me this error:
The entity or complex type XXXXX cannot be constructed in a LINQ to Entities query.
So... How do I return only selected data from only one entity?
Basically, I'm not sure why, but Linq can't create the complex type. It would work if you were creating a anonymous type like (sorry c# code)
var who = (from x in contect.Doctors
where x.Regeneration == 3
select new { Actor = x.Actor }).Single();
you can then go
var doctor = new Doctor() {
Actor = who.Actor
};
but it can't build it as a strongly typed or complex type like you're trying to do with
var who = (from x in contect.Doctors
where x.Regeneration == 3
select new Doctor { Actor = x.Actor }).Single();
also you may want to be careful with the use of single, if there is no doctor with the regeneration number or there are more than one it will throw a exception, singleordefault is safer but it will throw a exception if there is more than one match. First or Firstordefault are much better options First will throw a exception only if none exist and Firstordefault can handle pretty much anything
The best way to do this is by setting the wanted properties in ViewModel "or DTO if you're dealing with upper levels"
Then as your example the ViewModel will be:
public class DoctorViewModel{
public string Actor {get;set;}
// You can add as many properties as you want
}
then the query will be:
var who = (From d In contect.Doctors
Where d.Regeneration = 3
Select New DoctorViewModel {Actor = d.Actor}).Single();
Sorry i wrote the code with C# but i think the idea is clear :)
You can just simply do this:
Dim who= (From d In contect.Doctors
Where d.Regeneration = 3
Select d.Actor).Single
Try this
Dim who = contect.Doctors.SingleOrDefault(Function(d) d.Regeneration = 3).Actor

Entity Framework: How to get the EntitySetName of a TPT or TPH Entity

I have an Employee entity that inherits from a Person entity that inherits from a Resource entity (Employee -> Person -> Resource). Is it possible to programmatically get the EntitySetName of Employee (which should be Resources)?
I take the example from here...
http://msmvps.com/blogs/kevinmcneish/archive/2009/12/03/entity-framework-programmatically-determining-the-entity-set-name-of-an-entity.aspx
... and consider only the else case in the code snippet (so, we have no entity instance with a key):
// I have tested with EF 4.1/DbContext, for EF 4.0 forget this line
var objectContext = ((IObjectContextAdapter)dbContext).ObjectContext;
Type entityType = typeof(Employee);
string entityTypeName = entityType.Name;
var container = objectContext.MetadataWorkspace.GetEntityContainer(
objectContext.DefaultContainerName, DataSpace.CSpace);
string entitySetName = (from meta in container.BaseEntitySets
where meta.ElementType.Name == entityTypeName
select meta.Name).First();
string fullEntitySetName = container.Name + "." + entitySetName;
Now the problem is that this code throws an exception in First() because there is no BaseEntitySet with element type name equals "Employee". Obviously because there is only a set for the base type in the model = "Resource".
A possible fix is to change the second and third line above to:
Type entityType = typeof(Employee);
while (entityType.BaseType.Name != "Object")
entityType = entityType.BaseType;
string entityTypeName = entityType.Name;
This should give back "Resources" as the entitySetName IF...
Your entities are not derived from EntityObject (in this case it would probably work if you replace "Object" by "EntityObject" in the while loop above)
Your entities are not derived from another custom type which is not an entity in the model. For example if you have Resource derived from a base type MyBaseObject but didn't include it in the model (there is no DbSet<MyBaseObject> or ObjectSet<MyBaseObject>) then you would have to replace "Object" by "MyBaseObject" in the while loop.
The second limitation is not nice because you could have different non-model base types in your entity classes which would make the code above not very general applicable.
Perhaps there is a smarter way to get the model base type directly from the MetadataWorkspace, but I don't know.

Groovy Dynamic List Interaction

I am using an older version of grails (1.1.1) and I am working on a legacy application for a government client.
Here is my question (in psuedo form):
I have a domain that is a Book. It has a sub domain of type Author associated with it (1:many relationship). The Author domain has a firstName and lastName field.
def c = Book.createCriteria()
def booklist = c.listDistinct {
author {
order('lastName', 'asc')
order('firstName', 'asc')
}
}
Let's say I have a list of fields I want to use for an excel export later. This list has both the author domain call and the title of the column I want to use.
Map fields = ['author.lastName' : 'Last Name', 'author.firstName', 'First Name']
How can I dynamically call the following code--
booklist.eachWithIndex(){
key, value ->
println key.fields
}
The intent is that I can create my Map of fields and use a loop to display all data quickly without having to type all of the fields by hand.
Note - The period in the string 'author.lastName' throws an error when trying to output key['author.lastName'] too.
I don't recall the version of Groovy that came with Grails 1.1, but there are a number of language constructs to do things like this. If it's an old version, some things may not be available - so your mileage may vary.
Map keys can be referenced with quotes strings, e.g.
def map = [:]
map."person.name" = "Bob"
The above will have a key of person.name in the map.
Maps can contain anything, including mixed types in Groovy - so you really just need to work around string escapes or other special cases if you are using more complex keys.
You can also use a GString in the above
def map = [:]
def prop = "person.name"
map."${prop}" = "Bob"
You can also get a map of property/value off of a class dynamically by the properties field on it. E.g.:
class Person { String name;String location; }
def bob = new Person(name:'Bob', location:'The City')
def properties = bob.properties
properties.each { println it }

Rendering joinTables as a list in Grails

I've got two domain classes: Car and Driver. I'd like to make a gsp view that displays the Car and Driver info in a list that looks more or less a default scaffolded list. For example:
Make Model Driver Age
------------------------
Chevy Nova Joe 20
Chevy Nova Mike 30
Chevy Nova Sally 40
Here's the domain classes:
class Car {
String make
String model
static constraints = { }
static hasMany = [ drivers : Driver ]
static mapping = {
drivers joinTable: [name: 'Car_Driver', column: 'DRIVER_ID', key: 'CAR_ID']
}
}
class Driver {
String name
int age
static constraints = { }
}
Make a car and give it a few drivers:
def car = new Car(make: 'Chevy', model: 'Nova')
def driver1 = new Driver(name: 'Joe', age: 20)
def driver2 = new Driver(name: 'Mike', age: 30)
def driver3 = new Driver(name: 'Sally', age: 40)
car.addToDrivers(driver1)
car.addToDrivers(driver2)
car.addToDrivers(driver3)
car.save()
What do I need to do in my CarController and/or gsp view to make a joined list happen (and still work with pagination)?
If a Driver can have only one Car, you need a Driver to reference Car and just to render scaffolding list for a Driver.
To tweak list columns, you'll have to grails generate-views.
If a Driver can have many Cars, and you don't want to pull Car_Driver table into visible domain model (it has no own domain meaning), make a scaffolding-like list action using SQL query result as a cardriverInstancesList. Like here: SQL/Database Views in Grails.
Just check that result is a PagedResultList. If not, you can create a PagedResultList by hand, it is easily constructed from a List and totalCount, which you can find with SQL.

Resources