Grakn, create entity composed by entity? - graph

I'm very new on GRAKN.AI and I'm wondering if in a GRAKN's graph I can create an "entity" composed by an "enitity". I know I can do the following code:
table sub entity
has book;
book sub resources datatype string;
But can I relate the "book" as an entity to the "table" ??
I need to have "book" as a complex concept and not as a simple resource.
Thanks,
Davide.

An alternative solution is to go through a relationship which allows you to define things more explicitly. For example,
To define a relationship you start by defining roles which provide context for how things relate to each other. For example:
insert
thing-on-top-of-table sub role;
table-with-thing-on-top sub role;
You then say how these roles link to the relationship and to the entities:
insert
sits-on sub relation
relates thing-on-top-of-table
relates table-with-thing-on-top;
table plays table-with-thing-on-top;
book plays thing-on-top-of-table;
The above is pretty much the schema of your simple knowledge base.
Now we can add some data. Let's say some book is on top of some table:
insert
$book isa book;
$table isa table;
(thing-on-top-of-table: $book, table-with-thing-on-top: $table) isa sits-on
Naturally you can expand things from here. For example you can give your book a title via a resource.
Side Note: Resources Vs Entities
The basic rule of thumb for relating something as a resource or as another entity depends on how much information you want to express in the model as well as if something can be defined by a data literal (e.g. String, Int, Long, etc . . . ).
For example a book is an entity because it is made up of multiple resources which help identify the book. I.e. the title, isbn, etc. . . those resources on the other hand are simple data values. A title is nothing but a string so there is no reason to make the title an entity, that should be fine as just a resource.

You couold model two entites bookand table and have a relation that you could call something like belongs and add the roles you need e.g. book-role and table-role
If the concepts are hierarchically related you can use inheritance.
table sub entity
has some property
book sub table
has additional property
Inheritance is usefull for classification you can easily understand that two sub entities are related and both can be retrieved by querying the parent.
match $t isa table;
would return the books as they are children entities of table.

Related

Symfony2 - extending existing non-abstract entity?

Let's say I have a Setting entity with some fields like IntValue, dateValue, stringValue and some linked entities, like countries (ManyToMany to entity Country), languages (ManyToMany to Language) etc.
Settings are created by users and assigned to specific objects (not important here, but I wanted to clarify).
Now I suddenly need to have UserDefaultSetting, which will be the same, but with additional user field (ManyToOne to User entity).
I tried to extend existing Setting entity class with one more field added. The problem is, as I looked at the schema update SQL, it created new table for the new entity, but without all the tables needed to ORM connections (mostly ManyToMany). Just one table with "scalar" fields.
So previously I've had setting table with int_value, date_value etc. but also setting_country and setting_language tables, linking ManyToMany relations. After creating child entity, Doctrine created only user_default_setting table with int_value, date_value etc. and additionally user_id column, but I can't see any relation/link tables.
I know I should've been do it with abstract base entity class, but at the time I started, I didn't know that and now part of the project is on production (don't look at me like that, I blame the client) and I don't want to change that "base" class now. Can I inherit everything from non-abstract entity class in a way it will work?
UPDATE: everything explained. See Cerad's comment. Thanks!

Comment entity related to Article or Product

I have entities "Article" and "Product". Now I want to add comments to these 2 entities. Should I create 2 different entities "ArticleComment" and "ProductComment" with the same properties, and build a ManyToOne relation to their respective entity, or create a single "Comment" entity and find a way to build a relation to both "Article" and "Product" entities. Considering solution #2, how could I do that ?
Considering solution #2, how could I do that ?
One way would be to use Single Table Inheritance
Single Table Inheritance is an inheritance mapping strategy where all classes of a hierarchy are mapped to a single database table. In order to distinguish which row represents which type in the hierarchy a so-called discriminator column is used.
This means that you can easily create two separate entities ArticleComment and ProductComment both extending Comment. Then you use the advantages DiscriminatorMap column provides.
Your Comment entity could hold a relation called parent for instance that would refer to either your Article or Product entities. By creating new instance of ArticleComment or ProductComment your discriminator map field would be automatically populated depending on which type you're using.
This would also give you advantages with using DQL to query related comments by their type. Example from documentation:
$query = $em->createQuery('SELECT u FROM Doctrine\Tests\Models\Company\CompanyPerson u WHERE u INSTANCE OF Doctrine\Tests\Models\Company\CompanyEmployee');
And more. You can read that chapter here. Of course this is just a sample and you can use completely different approach.

Many to many relationship with junction table in Entity Framework?

I'm trying to create a many-to-many relationship in Entity Framework (code first), according to the following post: Database design for limited number of choices in MVC and Entity Framework?
However, I can't get it to work properly, and I'm sure I'm doing something very simple the wrong way. Here's the diagram I have no from my attempts:
The point of the junction table is that I need to have an extra property, Level, in the relationship, so I can't just go with a direct relationship between Consultant and Program. I added the ConsultantProgramLink entity manually in the designer, and then added associations to Program and Consultant respectively, selecting to add a FK for each, and then made them both primary keys. But when I do it like this it doesn't work as I expected:
If I had done a direct association between Consultant and Program, I would have been able to refer to, say, Consultant.Programs in my code. But that doesn't work now with the junction table. Is there any way to remedy this, or do I always have to go through the junction property (Consultant.ConsultantProgramLink.Programs)? In any case, even if I do try to go through the junction property it doesn't help. I can do Consultant.ConsultantProgramLink in my code, but another dot doesn't give me the navigation property Programs (which for some reason also became simply Program, why? Can I just rename them if I eventually get access to them at all?).
So what am I doing wrong? Why can't I access the properties through dot notation in my code?
Once you model a junction table as an entity you indeed lose direct many-to-many relation between Consultant and Program. That is how it works. You will either have direct many-to-many relation or additional properties in the junction table. Not both. If you want both you can try creating custom Programs property on Consultant and use linq query to get related programs:
public IEnumerable<Program> Programs
{
get
{
return this.ConsultantProgramLinks.Select(l => l.Program);
}
}
The example is also the explanation of your last problem. You can't have Program property on ConsultantProgramLink because it is a collection of related entities, not single entity (it should be called ConsultantProgramLinks). The property in ConsultantProgramLink entity is called simply Programbecause it represents single entity not collection.
Edit:
If you need each Program to be automatically associated with each Consultant you must enforce it when you are going to create new Program. Having junction table exposed as separate entity will probably allow you achieving it easily:
var program = new Program();
...
context.Programs.AddObject(program);
var ids = from c in context.Consultants
select c.Id;
foreach (var id in ids)
{
var link = new ConsultantProgramLink
{
ConsultantId = id,
Program = program
};
context.ConsultantProgramLinks.AddObject(link);
}
context.SaveChanges();
If you add new Consultant you will have to create links to all programs in the same way.
The disadvantage is that if you have for example 1000 consultants this construct will create 1001 database inserts where each insert will be executed in separate roundtrip to the database. To avoid it the only option is either use stored procedur or trigger on Program table.

Using ExecuteQuery() with entity framework, entity class

I am trying to jump from ASP Classic to asp.net. I have followed tutorials to get Entity Framework and LINQ to connect to my test database, but I am having difficulties figuring out ExecuteQuery(). I believe the problem is that I need an "entity class" for my database, but I can't figure out how to do it. Here is my simple code:
Dim db as New TestModel.TestEntity
Dim results AS IEnumerable(OF ???) = db.ExecuteQuery(Of ???)("Select * from Table1")
From the microsoft example site, they use an entity class called Customers, but I don't understand what that means.
Entity Framework comes with a visual designer. In that designer, you connect to your existing database, and you select all the tables (and possibly views) from your database that you want to work with.
From that selection, EF will generate entity classes one for each of your tables, e.g. if you have a Customers table, you'll get a Customer class, if you have a Products table, you get a Product class.
Those classes represent (by default) your table structure 1:1 - e.g. each column in your table gets translated into a property on the class.
Once you have that, you're no longer dealing with SQL statements and stuff like ExecuteQuery() - you leave that to EF to handle for you.
You just ask for what you need, e.g. all your customers from a given state:
var ohioCustomers = from c in dbContext.Customers
where c.State = "OH"
select c;
This statement will return an IEnumerable<Customer> - a list of customers that matches your search criteria.

How do you avoid the n+1 problem with SubSonic?

Ayende has a blog post detailing how to combat the "n+1" problem in nHibernate. In essence, the problem is this:
Assume you have two tables, "BlogPosts" and "Comments" with a one-to-many relationship between them (i.e. each BlogPost can have multiple Comments). Now, let's say you want to execute the following nested for loop:
foreach (BlogPost post in blogposts)
{
foreach (Comment comment in post.Comments)
{
// Do something
}
}
From what I understand, the classes that SubSonic generate are lazyload by default (I don't want to turn this off completely because it's useful in most circumstances, just not this one). That means that every time the inner loop is executed (i.e. when post.Comments is accessed), a separate query must be sent to the database to retrieve the comments.
So if you have 80 blog posts, that's 1 query to get the list of blog posts, then 80 queries to get the comments for each of them. If the comments were eager loaded, however, this would be reduced to 1 query.
Is there any way to combat this problem in SubSonic currently?
Unless you create a query to select from Comment based on post IDs, I don't think there's a way to combat it. This would get you down to two. One query to select the post IDs you want, then another to get all the comments for that list of post IDs.
I think what you should do is create a partial class method that will get all the comments. Not so clean but should work.
I too use partial classes and load related table classes like so:
Partial Public Class Book
Private _Author as Database.Author
Property Author() as Database.Author
Get
If _Author is nothing then
' Load the author class here.
End if
return _Author
End get
Set
'....
End Set
End Property
End Class

Resources