This project has moved. For the latest updates, please go here.

how to implement entity inheritance in BrightstarDB

Oct 28, 2015 at 2:06 PM
hello,
i am working on publishing university data as link data using BrightstarDB.
i have this entities hierarchy:
AcademicOrganization (ID, Title, Description, OfferesDegree)
-- University (ID)
-- College (ID)
-- Department (ID)
AcademicDegree (ID, Title, Description, OfferedBy)

i created a view for University, but i don't know how to access Title, Description set by parent entity (AcademicOrganization).

thank you!
Coordinator
Oct 29, 2015 at 9:44 AM
Hi,

Thanks for taking the time to repost your question from the old list!

It should be pretty easy to get an inheritance hierarchy. You just need to declare it on your interfaces:
    [Entity]
    public interface IBaseEntity
    {
        [Identifier("http://example.org/entities/")]
        string Id { get; }

        string BaseStringValue { get; set; }
    }

    [Entity]
    public interface IDerivedEntity : IBaseEntity
    {
        DateTime DateTimeProperty { get; set; }
        ICollection<IBaseEntity> RelatedEntities { get; set; }
    }
The code generator will generate a DerviedEntity class that implements both interfaces. It doesn't copy the inheritance hierarchy from the interfaces because you could potentially have multiple inherited interfaces. The context will also contain collections for both the base and the derived entity types. In your code you should find that you can query either on the base class or the derived class. e.g.
// This would find an instance of BaseEntity OR DerviedEntity that matches
var b = context.BaseEntities.FirstOrDefault(x=>x.BaseStringValue.Equals("foo"));

// This would only find instances of DerivedEntity that match
var d = context.DerivedEntities.FirstOrDefault(x=>x.BaseStringValue.Equals("bar"));
Does that help ? If I've missed the point in your question let me know!

Cheers

Kal
Jun 28, 2016 at 9:05 AM
thank you for your response.
i tried this sample:
    [Entity("foaf:Organization")]
    public interface IOrganization
    {
        [Required]
        [PropertyType("rdfs:label")]
        string Title { get; set; }

        [PropertyType("rdfs:comment")]
        string Description { get; set; }
    }

    [Entity("aiiso:College")]
    public interface ICollege
    {
        [Identifier("unidata:College/")]
        string Id { get; }

        IUniversity University { get; set; }
    }
now I created a controller
and its views like this
@model IEnumerable<UniversityData.Models.ICollege>

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

<p>
    @Html.ActionLink("Create New", "Create")
</p>
<table class="table">
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.Title) //I got proplem here
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Description)
        </th>
        <th>
now i get this error message:
Compiler Error Message: CS1061: 'UniversityData.Models.ICollege' does not contain a definition for 'Title'
i could change the model for the view from 'ICollege' to 'College'
but the controller passes a IEnumerable<ICollege> not IEnumerable<College>

i hope the problem is clear

Thank you!
Coordinator
Jul 1, 2016 at 9:25 AM
Hi,

You need to add the inheritance to the ICollege interface like so:
    [Entity("aiiso:College")]
    public interface ICollege : IOrganization
That should then pick up the inherited Title property in the controller.

Cheers

Kal
Jul 1, 2016 at 1:03 PM
i have previously added the ICollege : IOrganization inheritance (forget it in the code here).
and still facing the same problem!
i seems like views can't see the Title on the ICollege interface, instead, it sees it in the final College class
thank you
Jul 1, 2016 at 10:42 PM
i have uploaded my VS Project to GitHub if you would like to look at.
https://github.com/wisamx/UniversityData
I appreciated
Jul 3, 2016 at 7:59 AM
I tried modifying the nerdDinner project by adding the IMeeting interface, and transfer the IDinner.Title property to it, like this:
    [Entity]
    public interface IMeeting
    {
        [Required(ErrorMessage = "Please provide a title for the dinner")]
        string Title { get; set; }
    }
    [Entity]
    public interface IDinner : IMeeting
    {
        [Identifier("http://nerddinner.com/dinners/")]
        string Id { get; }

        // string Title { get; set; } // Moved to IMeeting

        string Description { get; set; }
The property BrightstarDB.Samples.NerdDinner.Models.IDinner.Title could not be found.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.ArgumentException: The property BrightstarDB.Samples.NerdDinner.Models.IDinner.Title could not be found.

@Html.DisplayNameFor(model => model.Title)
I have got the same problem!?
I am really confused with this problem, and can't find the answer for it.
Coordinator
Jul 4, 2016 at 8:16 AM
Hi,

It looks like this is not a B* issue but a problem with ASP.NET MVC. Please see this question (and the answer) at Stack Overflow: http://stackoverflow.com/questions/7968304/inherited-interface-property-not-found-by-model-binding

This looks like exactly the problem you have. It would appear that the only solution is to change your model to use the implementation class rather than the interface. E.g:
@model IEnumerable<UniversityData.Models.College>
Cheers

Kal
Jul 4, 2016 at 7:16 PM
I am trying to write my code to work on the implementation class rather than the interface.
but I am facing a littler problem with the Index controller and the index view.
I am not sure how to convert controller result from IEnumerable<UniversityData.Models.ICollege> to IEnumerable<UniversityData.Models.College>.

now I'm using this code to do the conversion:
        public ActionResult Index()
        {
            var colleges = from c in _dataContext.Colleges
                           select c;
            List<ICollege> oldList = colleges.ToList();
            List<College> newlist = new List<College>();
            foreach (ICollege item in oldList.ToList())
                newlist.Add((College)item);
            return View(newlist);
        }
I appreciated if you could suggest a better way to do the conversion.

thank you so much for your help :)
Coordinator
Jul 6, 2016 at 8:01 AM
You should be able to use the Cast<T> operator from LINQ:
var newlist = colleges.Cast<College>().ToList();
Hope that works for you!

Cheers

Kal