while defining plays in grakn, do we have to define plays separately as well? - vaticle-typedb

define t1 sub entity, plays employee;
UNKNOWN: ai.grakn.exception.GraqlQueryException: employee doesn't have an 'isa', a 'sub' or an 'id'. Please check server logs for the stack trace.

This employee doesn't have an 'isa', a 'sub' or an 'id' means that you haven't defined employee in your schema, so Grakn does not know how to interpret:
define t1 sub entity, plays employee;
Make sure to define employee sub role;

Related

grakn grqal match query return less results than expected

The grakn server version is 1.3.0.
I have a 4000+ line CSV file, each line stands for an employee profile record. The CSV file has a column called Reportingline, which stands for the EmployeeID of the employee's line manage.
I can successfully migrate my CSV data into my Grakn keyspace, but when I use the following query I can only get one record returned.
match
$e isa employee has report-line "00136450";get;
without 'contains' only 1 result returned
The results are correct when I change the above query as below, but significantly this is a big performance hit.
match
$e isa employee has report-line contains "00136450";get;
with 'contains' the result is correct
Can anyone point out what is wrong with my query? How do I get the full results without contains keyword?
I use the following schema to define an employee
employee sub entity
plays superior
plays subordinate
has employee-id
has employee-name
has report-line
has bu
has email
has phone-number
has division
has title;
employee-id sub attribute datatype string;
employee-name sub attribute datatype string;
report-line sub attribute datatype string;
bu sub attribute datatype string;
email sub attribute datatype string;
phone-number sub attribute datatype string;
division sub attribute datatype string;
title sub attribute datatype string;
I use the following template to migrate the CSV data.
$x isa employee,
has employee-id <EmployeeID>,
has employee-name <EmployeeName>,
has report-line <ReportLine>,
if(<BU>!=null) do { has bu <BU>,}
has email <Email>,
if(<PhoneNumber>!=null) do { has phone-number <PhoneNumber>,}
if(<Division>!=null) do { has division <Division>,}
has title <Title>;
Thank you for reporting this issue. I am writing here to confirm that the bug has been fixed in Grakn 1.4.0.

Entity Framework throws DBUpdateConcurrencyException if table has trigger defined

While working on RESTful service in ASP.NET with support of Entity Framework and SQL Server 2014 as DB engine, I met some unexpected obstacle on my way.
I've prepared some dummy case which exactly explains what kind of problem I'm facing right now.
I've got database in SQL Server named "dummy_database". It contains only one table - Person - and one trigger - TR_Person_Insert - which is responsible for adding some extra data (current date and time in this particular case) to every single record before add the record to the "Person" table. Code of database structure is included below:
USE dummy_database;
GO
IF EXISTS (SELECT * FROM sys.tables WHERE name LIKE 'person')
DROP TABLE [person];
GO
IF EXISTS (SELECT * FROM sys.triggers WHERE name LIKE 'TR_Person_Insert')
DROP TRIGGER [TR_Person_Insert];
GO
CREATE TABLE [dbo].[person]
(
[id] INT IDENTITY(1, 1),
[name] NVARCHAR(256) NOT NULL,
[surname] NVARCHAR(256) NOT NULL,
[age] INT NOT NULL,
[valid_from] DATETIME2 (7),
CONSTRAINT PK_Person_ID PRIMARY KEY ([id])
)
GO
CREATE TRIGGER TR_Person_Insert ON [dbo].[person]
INSTEAD OF INSERT
AS
BEGIN
INSERT INTO [dbo].[person] ([name], [surname], [age], [valid_from])
SELECT i.[name], i.[surname], i.[age], GETDATE()
FROM inserted i
END
GO
Then I created dummy RESTful Service using ASP.NET and added Entity Framework with Database First approach to it. The code of one and only existing method of that Service is as below:
[RoutePrefix("api/person")]
public class DummyController : ApiController
{
[HttpPost, Route("")]
public IHttpActionResult AddPerson(PersonDto data)
{
using (var ctx = new DummyDatabaseModel())
{
var person = new person
{
name = data.Name,
surname = data.Surname,
age = data.Age
};
ctx.people.Add(person);
ctx.SaveChanges();
}
return Ok();
}
}
The problem is with saving changes method called on database's context. This method throws DBUpdateConcurrencyException exception with additional information as below:
An exception of type 'System.Data.Entity.Infrastructure.DbUpdateConcurrencyException' occurred in EntityFramework.dll but was not handled in user code
Additional information: Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded.
I'm aware of the fact that this exception is caused by trigger, which is fired instead of regular 'insert' routine on database's side.
The question I ask is - how to get rid of this kind of exception without abandoning trigger in database. I'm out of ideas and to be frank - I count on your tips or solutions, if you faced same problem in the past.
Thank you for your help.
I had the same problem, in my case, the trigger was the expression "instead of insert"
Ex.
Create trigger TR_AA on TbAA INSTEAD OF INSERT ....
I changed the expression by "AFTER INSERT" It's work for me!
Ex.
Create trigger TR_AA on TbAA AFTER INSERT ....

Many to one relationship, unwanted JOIN

I have many to one relationship defined within my model:
Project.CreatedBy = ApplicationUser.Id:
class Project{
[Required]
public ApplicationUser CreatedBy {get; set;}
}
With mapping:
modelBuilder.Entity<Project>().HasOptional(i => i.CreatedBy).WithOptionalDependent().WillCascadeOnDelete(false);
Unfortunatelly, when I try to retrieve all users from DbContext by:
var users = context.Users;
Generated SQL looks like:
SELECT
[...]
FROM [dbo].[AspNetUsers] AS [Extent1]
LEFT OUTER JOIN [dbo].[Projects] AS [Extent4] ON ([Extent4].[CreatedBy_Id] IS NOT NULL) AND ([Extent1].[Id] = [Extent4].[CreatedBy_Id])
So when certain user have created 10 projects, the user entity is multiplied 10 times. It makes me impossible to look for that user by his username:
context.Users.Single(u => u.Username == "test")
because it would give me Sequence contains more than one element exception.
Do you have any idea how to avoid that extra join?
I suspect it has something to do with modelBuilder declaration. I've been googling about this, but never found any solution.
Any materials about modelBuilder and defining relationships with it would be really appreciated too.
The mapping...
modelBuilder.Entity<Project>()
.HasOptional(i => i.CreatedBy)
.WithOptionalDependent()
...expresses this as a 1:1 association, not the 1:n association you intend it to be.
So change the mapping into one-to-many:
modelBuilder.Entity<Project>()
.HasOptional(p => p.CreatedBy)
.WithMany()
.HasForeignKey(p => p.CreatedBy_Id);
I'm not sure why EF joins in the Project when you query User because the association is optional), but a proper 1:n mapping will stop this.
Use
.FirstOrDefault()
instead of Single.
This method will return first object or null if object is not found. Single method throws exception if more than one element is selected.
You can also use
.First()
But this method will throw exception if no elements found.
PS I'm not sure if it's a typo, but you have to use double equal sign, like that:
context.Users.Single(u => u.Username == "test")
And keep in mind that usually in these cases LoweredUsername column is created and used for compare:
context.Users.Single(u => u.LoweredUsername == providedUsername.ToLower())
Reasons for that:
Someone can type John instead of john
Indexing on SQL server side works in this case
I suppose in ApplicationUser you have
public virtual ICollection<Project> Projects { get; set; }
Please see turn off lazy loading for all entities in MSDN
Or to turning off lazy loading for specific navigation properties make the Projects property non-virtual

Generic function in VB.net

I have 2 different user account type and they both are stored in their respective tables (Members in Member table and Admin in Administrator table). Now i want to create a common function to access user info for any type of user, so i was looking a for generic function but i am stuck with returning respective class, I have create 2 class MemberInfo for normal users and AdminInfo for Admin usersNow if the generic class passed to this function is MemberInfo than it should process normal user details and return MemberInfo class, and if it's admin users, then it should return AdminInfo class.
Here is something what i have tried but unable to achieve my goal.
Public Function GetAllMembers(Of T)(ByVal accountType As AccountType) As List(Of T)
Dim T_ReturnValue As List(Of T)
Dim returnType As Type = GetType(T)
If returnType Is GetType(MemberInfo) Then
Dim _list As New List(Of MemberInfo)
With New OleDbDataAdapter("SELECT ACCOUNT_NO, COUNTRY FROM Member", Globals.DatabaseConnection)
Dim dt As New DataTable
.Fill(dt)
For Each row As DataRow In dt.Rows
Dim memberInfo As New MemberInfo
memberInfo.AccountNo = row("Account_No").ToString
memberInfo.Country = row("Country").ToString
_list.Add(memberInfo)
Next
End With
Return DirectCast(_list, List(Of T))
End If
End Function
Can anyone help me how i can return respective class, for now i wanted to return memberinfo class only.
Two ways:
You can have two overloaded functions that return different classes.
You can declare the function as Object, and return either class.
You can follow these steps.
Create an abstract class say "User" . And then Member and Admin has to extend that base class user. Assuming, both has same set of properties and that is why you have started using T to make it generic. But as you have said both has different DB table store.
If you different methods defined for Member and Admin, you can segregate them by using interface. Say Member can Send Friend request, so you can have an interface ( Say ISendRequest), that will have Send method definition only. And if Admin can Add new member ,then you can have interface say IAddMember, and Admin will implement IAddMember , Member will implement, ISendRequest.
KEY point Now, define an interface say IGetAllUser with method GetAllUser and User class has to implement that, but it will have abstract method GetAllUser. So point here is you have to have to write this one GetAllMembers, instead each derived class will have method to get corresponding List .
Sample code snippet. This can even accommodate the scenario if both Member and Admin has different properties.
But if you have same properties, then you can define a function in Base class, that takes Datatable and just sets required properties, as both member and admin has same properties. So the sole purpose of GetAllUsers implemented in Member and Admin class is to pass required table name to Data Access layer and get DataTable and pass that to function defined in base class to set required properties and build List of User.
public interface IGetAllUsers
{
List<User> GetAllUsers();
}
abstract class User : IGetAllUsers
{
public abstract List<User> GetAllUsers();
}
class Member : User
{
public override List<Member> GetAllUsers()
{
// Assuming there is data access layer, to get details
}
}
class Admin : User
{
public override List<Admin> GetAllUsers()
{
// Get all admin
}
}
Right. Before addressing your specific question, I want to start at the lower level.
In theory, an admin is a user, so at database level this should rather be implemented so that there is a [Users] table that stores all kinds of users including admins. Then you should add another table called [Admins] which links to the [Users] table through an FK and stores all additional fields that relate to admins only. This is called ISA / inheritance relation in RDBMS theory.
At application level, this will translate to two business classes, one for [User] and one for [Admin], where [Admin] will inherit from [User] class. You can then write a function that returns a [User] object. Since [Admin] inherits from [User], polymorphism will allow you to return [Admin] object from the same function. Then your caller can confirm the returned object type either through type checking, or you can store a boolean field in [Users] table called IsAdmin that will be true for administrators.

How does a class member gets updated automatically in a Sub routine / function even if I pass in ByVal in VB.NET?

Can anyone help explain why the following will change a value in an object's member even if I pass it in ByVal?
Scenario: The name of the person is 'Sab' but when i pass the object in the sub routine, the name changes to 'John'.
I thought object types are passed in by reference only and should not be changed unless forced. Is this a feature in .NET and what is this behavior called?
Sub Main()
Dim p As New Person
p.name = "Sab"
DoSomething(p)
Console.WriteLine(p.name) ' John
Console.Read()
End Sub
Public Sub DoSomething(ByVal p As Person)
p.name = "John"
End Sub
Writing to p.name is not the same as writing to p. ByVal prevents the parameter itself from being modified, e.g.
p = New Person
If you want to prevent the properties of Person from being written to, then you need to re-design the Person class to be immutable instead of mutable. Whether this is an appropriate thing to do depends on how you want your code to behave.
Example:
Public Class Person
' All fields are private
Private _name As String
' All properties are read only
Public ReadOnly Property Name As String
Get
Return _name
End Get
End Property
' Field values can *only* be set in the constructor
Public Sub New(name As String)
_name = name
End Sub
End Class
An instance of an object is a reference - it's a pointer to the object. If you pass any object by value, you are passing it's reference by value. Effectively, there is no difference in passing an object by value or by reference. .Net creates a new copy of the reference and passes it's value to your method but the new copy of the reference still points to the same object. Some folks say that "all objects are passed by reference" but this is not true, the reference to the object in the called method is NOT the same as the reference in the caller but they point to the same object.
If you really want to pass a copy of the object such that the called method may not modify the originals' properties, then you need to create a copy. See discussions about shallow vs deep copies and be careful to understand references to objects vs simple data types. Do think about your design though. It's rare to actually need to create a copy rather than a new object.

Resources