I have an EF4.Model with Category table which will be using the NestedSet pattern to store child/parent relation, which I think means that EF4 cannot help with its factory methods in retrieving the children becoz there will be no children or parentId, just left and right.
I created an CategoryModelExtensions static class, but for the children to be retrieved I will need a variable to refer to the repository.
But how can I inject that variable when constructors are not allowed in static classes?
I didn't want to create the Children() method in the repository for I want to be able to write.
Category c = _repo.Get(1);
IList<Category> children = c.Children();
Help? If my question is not clear please mention it here and I will update it as needed.
You could just pass it explicitly:
public static IList<Category> Children(this Category category, IMyRepository<Category> categories)
{
// do stuff
}
IList<Category> children = c.Children(_repo);
Related
In grails, how do I find subdomain using domain instances
Let say I have
class Family {
Integer id
Parent parent
}
class Parent {
Interger id
static hasMany = [children: Child]
}
class Child {
String name
}
So in controller,
Parent mom = Family.findById(1).parent
so now, how do I use mom to get a child with name == "Child" in parent?
Is it even possible?
I think this should work.
Child child = mom.children.find { it.name == 'child' }
But I do not recommend using this kind of queries. Grails has many ways for querying you can read about it here http://gorm.grails.org/latest/hibernate/manual/index.html#querying. I also recommend to you this guide http://guides.grails.org/querying-gorm-dynamic-finders/guide/index.html its about dynamic finders in contrast to queries that use groovy collection methods for querying.
I hope its help full
You can use the criteria API for that:
Parent.withCriteria {
children {
eq("name", "Bob")
}
}
In this example children will be joined to the parent. And all parents will be returned, that have a child called "Bob".
You can simply use closure findAll{} this way:
def childrenList=mom.findAll{it.children.each{
if(it.name=='child')
return it
}
}
This will give you a list of all the children objects with name 'Child'.
As #user615274 has suggested, the accepted solution works but that it may have performance issues.
One feature that Grails shine is the dynamic query. I would modify the Child domain and use dynamic query. eg.
Since Parent "hasMany" relation to Child, the child "belongsTo" the Parent
class Child {
String name
Parent parent
// or static belongsTo = [parent:Parent]
}
Once this relationship is setup, then you can use dynamic query
def child = Child.findByParent(mom) // return the first matching result
def children = Child.findAllByParent(mom) // returns a list of matching result
I hope this helps.
I am new to the .NET MVC. However this "problem" I am stuck at looks pretty common, I cannot find any tutorial or stackoverflow thread that explains how to do it properly.
I have a class, MyClass which has two attributes of same type
public class MyClass : IEquatable<MyClass>
{
public virtual MyClass LeftChild { get; set; }
public virtual MyClass RightChild { get; set; }
...
}
Now I have problem with nhibernate mapping. At first I tried one-to-one mapping. I created new instance and DO NOT set Childs , persisted it (lets say Id=1), and pass this instance to View and I expected that RightChild will be NULL and LeftChild will be NULL. But in the debbug mode i can see, that the RightChild was set to MyClass with Id=1 (Like MyClass instance set itself to this attribute) and same with LeftChild.
Mapping MyClass.hbm.xml
...
<one-to-one name="LeftChild" class="MyClass"/>
<one-to-one name="RightChild" class="MyClass"/>
...
Is it right approach to do it with one-to-one or I should use something else ?
References, where our table contains foreign keys, are almost always best to map with many-to-one.
Simply think about it as a standard reference to other instance (Country, Currency)... which is accidentally of a same type.
<many-to-one name="LeftChild" column="LeftChild_ID" class="MyClass"/>
<many-to-one name="RightChild" column="RightChild_ID" class="MyClass"/>
The only challenge I see, is to be sure that the server part (C# code, app) will be properly setting these values. There is not bi-directional mapping in this kind of persisted information. Each sibling, needs its own information who is right who is left.
I mean, comparing with Similar mapping: parent-child (also same type). In that case we would have child having reference to parent, and parent having collection of children.
But that is not the same here.. again.. we map just one side of the relation.
A one-to-one is not suitable here, because it requires two tables, with (almost) the same amount of rows, sharing same column as a key... I like to use it, but for kind of Additional info... see:
NHibernate Dynamic Columns Number
NHibernate Optional Join generates insert instead of update
I'm having difficulties retrieving relationships when the relationship type is annotated with a #RelationshipType field.
The relationships look correct in Neoclipse, but I'm retrieving no results in my application.
The code that doesn't work is (simplified):
#NodeEntity
public abstract class Entity {
#RelatedToVia
private Collection<Relationship> relationships;
public Relationship relatedTo(Entity entity, String type) {
Relationship relationship = new Relationship(type, this, entity);
relationships.add(relationship);
return relationship;
}
...
}
and:
#RelationshipEntity
public class Relationship {
#RelationshipType
private String type;
...
}
The code that does work is:
#RelationshipEntity(type = "something")
public class Relationship {
...
}
However, this doesn't suit my use case (I have a bunch of different Relationship types between arbitrary combinations of Entity instances.
The full test code is below. Agency and Item are both subclasses of Entity.
// Create first entity
Agency arnz = agencyRepository.save(new Agency());
arnz.setCode("ARNZ");
agencyRepository.save(arnz);
// Create second entity
Item r123 = itemRepository.save(new Item());
r123.setCode("R123");
// Create parent/child relationship between entities
r123.relatedTo(arnz, EntityRelationshipType.PARENT);
itemRepository.save(r123);
// Retrieve entity from database
Entity entity = itemRepository.findByCode("R123");
// Verify that relationship is present
assertThat(entity.getRelationships().iterator().hasNext(), is(true));
The final line is where the test is failing. Any clues?
M
PS. I'm a rank amateur with Neo4j and just happened to find #RelationshipType, so I may well be doing something laughably wrong. I hope so!
Sorry to disappoint you, but during the retrieval the code right now doesn't look for the type class but rather for the type from #RelatedToVia or #RelationshipEntity or the field name relationships as relationship-type. But you're making a valid point, can you please raise in issue in JIRA?
Did you look into template.getRelationshipsBetween ?
Why don't you create individual classes for your relationships? What is the use-case for this approach?
My problem should be obvious, but I just don't see the light right now :-(
I have two domainclasses like this:
class Parent {
String name
static hasMany = [children: Child]
}
class Child {
String name
}
Now I should be able to find the Parent of a child by using the dynamic finder of the Parent like:
Parent.findByChildren([someChild] as Set)
But I get a hibernate error stating that I've got a grammar error in my hibernate SQL:
Caused by: java.sql.SQLException: No value specified for parameter 1
And for the reference: someChild IS a concrete instance. And I would like to avoid Child to have an explicit parent in the definition.
How then can I go from the Child to the Parent?
Best Regards,
Christian Sonne Jensen
Just to end this question, I wanted to report a solution to my "problem". I'm using a namedQuery in the Parent entity (Customer or Producer) like this:
Class Customer {
static hasMany = [channels: Channel]
static namedQueries = {
findByChannel {
channelId ->
channels {
eq 'id', channelId
}
}
}
}
Then I find the Customer like this:
def customers = Customer.findByChannel(channel.id).list()
In this way the Channel are relieved of the burden of knowing anything about who references it, and I don't have to do any artificial relationship tables.
I still think that it must be some kind of mistake that I cannot use one of the dynamic finders:
Customer.findByChannels([channel] as Set)
Maybe the dynamic finders doesn't take one-to-many relationsships into account, and only works for simple attributes??? (I'm using Grails 1.3.1)
Thanks for your replies though!
Christian Sonne Jensen
If you don't want the parent foreign key on the child, you'll have to create a join table for the parent that serves as a surrogate for the child:
class ParentalRelationship {
static belongsTo = [parent: Parent, child: Child]
}
You could then have helper methods on the parent to query for children through the ParentalRelationship object.
With your real implementation of Customers, Channels, and Producers, chances are that you'd want a many-to-many relationship anyways as a channel wouldn't belong to a single customer (or a single producer).
Maybe a better way is to write in the chield the belongsTo something like this:
static belongsTo = [parent: Parent]
And then you can use:
Chield c = ...
Parent parent = c.parent
I would invert it:
class Parent {
String name
static Set<Child> getChildren() {
Child.findAllByParent(this) as Set
}
}
class Child {
String name
Parent parent
}
This uses the same database structure (the child table has a foreign key to parent) but makes it easy to go from one side to the other without being explicitly bidirectional.
One thing does change. Instead of this:
def parent = ...
parent.addToChildren(new Child(...))
parent.save()
you do this:
def parent = ...
def child = new Child(parent: parent, ...).save()
This is more performant because you don't need to load the entire collection just to persist a new child.
I have a simple database from which I am generating Linq2SQL classes using a datacontext. In one part of my application I would like to load the entire relationship such that I get child records. In another part of the application I am passing that relation across the boundary between model and view and I would like to not pass the entire thing since the set of children is pretty large. Is there a way to not have these child classes exported in one section and be exported in another?
I am aware of setting the child property to False in the datacontext but that is a global change.
You can do it with the DataLoadOptions setting on the data context. You'll probably have some sort of builder class somewhere in your application. For the quickest and dirtiest solution, you could do something like the following...
public class SqlContextBuilder
{
public SqlContextBuilder(MyDataContext dataContext)
{
_dataContext = dataContext;
}
private readonly MyDataContext _dataContext;
public MyDataContext CreateEagerLoadingContext()
{
var options = new DataLoadOptions();
// set those options!
_dataContext.LoadOptions = options;
return _dataContext;
}
public MyDataContext CreateLazyLoadingContext()
{
// lazy loading happens by default
return _dataContext;
}
}
One of the solutions is to pass the relation as IQuerable. This will make sure that the relation is not executed until is it required. If you loop over the relation then it will be executed for each child.
Another technique might be to use DTO objects to create a ViewModel of which you like to pass. This means your ViewModel might be very similar to the interface.