I have an eloquent relationship for an object but I don't have an idea to filter the inner objects of the main object passing parameters.
There is an object called Venue in our project. It has many Classes objects. The class object belongs to many categories and has one Instructor object. We have the Categories table too. What I am trying to do is filter the class objects of the venue object using category_id in Category table and instructor_id in Instructor table.
$Venue = Venue::with('categories')
->with('classes.schedules')
->with('classes.categories')
->with('classes.instructor')
->rentable()
->findOrFail($venue_id);
I expect to pass the class_category_id and instructor_id to 'classes.categories' and 'classes.instructor' to filter classes of the single venue.
Related
I have two entities Parent and Child connected by an optional one-to-many relationship. I am trying to write a predicate that will allow me to do the following:
Only retrieve Parent objects that have Child objects in which a specific attribute is set, eg. name = 'John'
Retrieve Parent objects in which only the selected Child objects are populated. So in the above case, the childSet property would only contain John but not Mary or Peter.
Is there a way to do this in Core Data?
I don't know whether I should be drawing parallels, but unfortunately, that's the only way I can express my issue.
In SQL, suppose we have two tables:
Employee with columns Employee ID, Employee Name, Dept. ID
Deptartment with columns Dept. ID, Dept Name
The Dept ID. in the Employee table is a foreign key with that in the Department table.
Now suppose I want to fetch the following columns:
Employee ID, Employee Name, Department Name
using a SQL such as:
SELECT A.EMPLOYEE_ID, A.EMPLOYEE_NAME, B.DEPT_NAME
FROM EMPLOYEE A, DEPARTMENT B
WHERE A.DEPT_ID = B.DEPT_ID
How would one do this using Core Data in Swift? I guess I'm getting confused by only seeing references to
NSFetchRequest(entityName: entityName)
where the entityName refers to a single entity (table in relational DB lingo)
I'd really appreciate any pointers or examples that can help me clear my doubts.
Thanks
It is certainly possible to create a fetch request that is equivalent to your SQL query. More complex queries can be difficult if not impossible to achieve with a single fetch request. But I recommend trying NOT to draw parallels between CoreData and SQL, at least until you have got to grips with how it works.
To take your example, in the CoreData view of the world, Employee would be an entity with a relationship to another entity, Department. A fetch request based on the Employee entity will return an array of Employee objects, and (assuming you create subclasses of NSManagedObject for each entity) you can access the attributes with simple dot notation:
let employeeName = myEmployeeObject.employeeName
But you can use the same notation to traverse relationships equally easily:
let departmentName = myEmployeeObject.department.departmentName
You don't need to worry about joins, etc; CoreData handles that for you.
Now, suppose you try to do it "the SQL way". You can construct a fetch request based on the Employee entity, but specify "properties to fetch" which likewise traverse the relationship:
let fetch = NSFetchRequest(entity:"Employee")
fetch.propertiesToFetch = ["employeeID", "employeeName", "department.departmentName"]
For this to work, you would need to specify the "resultType" for the fetch request to be DictionaryResultType:
fetch.resultType = .DictionaryResultType
The results from this query would be an array of dictionaries containing the relevant keys and values. But the link with the underlying objects is lost. If you subsequently want to access any details from the relevant Department (or even the Employee), you would have to run a new fetch to get the object itself.
I'm trying to see if I can have a discriminator column come from another table, not part of the hierarchy. For example, imagine the following scenario:
PersonTable (PersonID, PersonTypeID, other fields)
EmployeeTable (PersonID, etc)
StudentTable (PersonID, etc)
PersonTypeTable (PersonTypeID, PersonCategoryCode)
I'm creating an abstract class Person, that is inherited into Student and Employee.
I want to have PersonCategoryCode column be the Discriminator column based on which Student or Employee objects are instantiated by EF.
Is this possible? Adding PersonTypeTable to PersonTable mapping's yields errors. PersonTypeID is unfortunately too dynamic to put into static edmx mapping.
so the story is very simple.
I have one table called Products and another Called categories. In addition, i have another table called ProductCategories that hold the relationship of catetories to their corresponding products (i.e, the table has two columns, ProductId, ColumnId).
For some reason, after adding all those table to my entity model, i don't have "Access" to it, hence i can do myentityModel.ProductCategories, so i could relational items between those two tables.
And yes, the ProductCategores table is added as "Association" to the entity model. i don't really understand that.
EDIT:
I do see that as part of creating new "Product" i can pass EntityCollection of "Category". So i do query from my entity model for a list of the matching categories that the user selected (on the webpage). so for example, i get (after query the model), an Objectset of "Category". However, i encountered two issues:
the 'AddObject' accept only EntityCollection, hence i need to re-create a set and then add all the objects from the ObjectSet to the entityCollection, in this process i need to detach it from the previous model and add it to the new collection. if not, i get an exception.
when i do the SaveChanges, i see that i get an exception that it was actually trying to Create new Category rather than adding new ProductCategory. again, am i missing something here?
Thanks.
This sounds like a Many-to-Many relationship. In your entity model, you don't need to declare the join table as a separate entity. Instead, you configure the relationship between the Products and the Categories as a Many-to-Many and add metadata about the join table. In Hibernate, you would have:
#ManyToMany(targetEntity=Categories.class, cascade={CascadeType.ALL}, fetch = FetchType.LAZY)
#JoinTable(name="tb_products_categories",
joinColumns=#JoinColumn(name="category_id"),
inverseJoinColumns=#JoinColumn(name="product_id")
)
#IndexColumn(name="join_id")
public List<Categories> getCategories() {
return categories;
}
When you query, the ORM layer takes care of determining SQL and traversing table joins.
Suppose I have
table Person
table Employee, which inherits Person.
I want to get a list of Person, regardless if this Person is Employee or not. How do you get entity framework to do that without joining the Employee table? C# is what I'm using. Thanks.
You need to make sure that you don't implicitly use any information from Employee.
If you do this:
var people = Context.People.ToList();
... Then me Entity Framework will initialize new instances of type Employee for those people who happen to be employees. This is because when you store an Employee in the database, you generally expect to get an Employee back when you select the same item.
Nor, for that matter, can you tell the Entity Framework to give you a Person when the stored value is an Employee. The Entity Framework will never give you back an incorrect entity type.
However, if you do just want to read the one table, there is a way to do that: Select the data from Person into a non-entity types, such as an anonymous type:
var people = Context.People.Select(p => new { Name = p.Name }).ToList();