LINQ to RDF - Wow

23 views
Skip to first unread message

Andrew Matthews

unread,
Jun 9, 2008, 5:42:42 AM6/9/08
to linqtord...@googlegroups.com
Hi Paul,

Thanks so much for this. It's clear I need to spend more time on my documentation and less on features. ;-)

1. The success or failure of the '>' operator will depend on the XML Schema Datatype of the datatype property you were using. If you were trying to use it with Decimal, it should have worked. The operators are fairly thoroughly defined in XML Schema. Sure you weren't trying to use it on a string type? ;-)

2. The standard ontologies are already defined for you in LinqToRdf.dll - i have a method that recursively walks the graph of loaded assemblies looking for ontology declarations. It will always find those declarations, so you usually only need to declare your own ontologies.

3. No, because it uses a namespace manager that uses the name as the key in a lookup table for namespaces.
3.1. that's what it ought to do. Do you have an example?

4. BTW: Tripple should be spelled as 'triple' ;-). I'm moving away from using the TripleStore object these days. Instead I assume a remote SPARQL endpoint, since the local SemWeb triple store is not an ideal platform. RDF was the old name for RdfDataContext. the Documentation is out of date.

5. Were your classes derived from OwlInstanceSupertype (I really should think up a nicer name). if they weren't, a safe cast would yield null.

6. you never ever do anything with the web site so it doesn't matter to me. But i don't see why not.

7. All part of LinqToRdf - you will have a copy of the SPARQL HttpHandler if you have LinqToRdf.
It appears that because I ONLY registered the prerequisites in the GAC, and not with VS.NET 2008, you would not have been able to find the assembly in the 'Add references' dialog to register it in your app. I'm going back to the old xcopy way of doing things, and I'll get rid of the GAC stuff - it was not a popular decision anyway.

8. the installer probably failed for reason 7. A new version is immanent.


Regards,
Andrew Matthews
Readify | Senior Developer
Suite 206 Nolan Tower | 29 Rakaia Way | Docklands | VIC 3008 | Australia
________________________________________
From: Paul Stovell
Sent: Saturday, 7 June 2008 4:30 PM
To: Andrew Matthews; Readify Tech
Subject: RE: LINQ to RDF - wow

Hi Andrew,

I guess the first thing that scared me away in the past is the number of technologies involved – RDF, its representation in N3, ontologies and their N3, OWL, SPARQL, triple stores etc. Then you have to get an endpoint to query. That's largely beyond your control, but perhaps your "getting started" pages could serve as a (really simple) guide to what those things are, assuming the user doesn't know a thing about semantic web?

Here are a few things that I ran into:


1.       Using greater than or less than in the query seemed to cause problems, but that may have been my fault – I'm not sure if I got the ontology right.

2.       Registering the standard Ontology attributes at the assembly levels seemed to cause things to break, so I commented them out.

3.       The namespace manager really doesn't like multiple namespaces with the same name being registered

o    Perhaps it could ignore them if the namespace declaration is the same (just accidentally registered twice?)

4.       Would it be possible to query the TrippleStore object directly, without creating the RdfDataContext

o    I think the document refers to it just as "RDF" class?

5.       In the method "AssignInstanceUriToOwlInstanceType" in the ObjectDeserializer class, it takes an OwlInstanceSupertype object, which for me kept being null causing a null reference exception.

o    I think this may be a bug in my code somewhere but changing the code to check for null first fixed it and it seemed to work OK.

6.       Could the test-sparql-endpoint project be an ASP.NET Web Application with a fixed port number rather than a web site project?

o    VS wouldn't let me open it until it registered it in IIS

7.       The document referred to someone's SPARQL query handler, but I couldn't find where to get it or how to set it up

o    In the end I just copied the DLL's from the Lib folder

8.       I didn't try the designer yet because I wasn't sure what components I needed to install. I can see how useful a designer for this would be; especially if it reverse engineers from the ontology.

o    Could the document provide a link to what I need to build it?

As far as Bindable LINQ goes, maybe design the UI and send it to me and I can let you know whether it would help?
Regards,
Paul Stovell
Readify | Senior Developer
Microsoft MVP: Visual Developer - Client Application Development

________________________________________
From: Andrew Matthews
Sent: Saturday, 7 June 2008 2:19 PM
To: Paul Stovell; Readify Tech
Subject: RE: LINQ to RDF - wow

Hi Paul,

Thanks!

Apart from the sporadic installer issues, that seems to have cropped up in 0.7, what ways would you do to improve the experience? I've found it really hard to get any kind of constructive criticism from the users, so if you have any feedback, I'd really appreciate it.

BTW: SPARQL is a inherently one-way protocol (at the moment) but do you think it's possible to leverage BINQ to get better performance out of LinqToRdf? I want to create a sexy demo app based on WPF accessing the contents of DBPedia (a semantic web export of the contents of wikipedia). Do you think we could create an app that would blow BOTH our trumpets together?

Regards,
Andrew Matthews
Readify | Senior Developer
Suite 206 Nolan Tower | 29 Rakaia Way | Docklands | VIC 3008 | Australia
________________________________
From: Paul Stovell
Sent: Friday, 6 June 2008 9:56 PM
To: Readify Tech; Andrew Matthews
Subject: LINQ to RDF - wow

For a while I've been dreaming of a way to serialize LINQ queries, send them over the wire to a web service, and have them evaluated on the other side. I wrote about this here:

http://www.paulstovell.com/blog/linq-to-soap-to-linq-again

Tonight I've been fooling around with Andrew's LINQ to RDF, and suddenly, it all clicked. I wanted to see if LINQ to RDF and semantic web technologies could solve the scenario I put in my blog post. Here's how I did it using LINQ to RDF.

I created a project with two solutions – Client, a console app; and Server, an ASP.NET web application:

[cid:image0...@01C8C8B4.BCFAF150]

The idea is I want my web application to expose data that I can query from any client, without having to define 89 different web service operations for all the queries I need. First, I created an ontology, which describes the data – a bit like an XSD or WSDL file. That's the BankData.owl file:

@prefix rdf:  <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix daml: <http://www.daml.org/2001/03/daml+oil#> .
@prefix log: <http://www.w3.org/2000/10/swap/log#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix owl:  <http://www.w3.org/2002/07/owl#> .
@prefix xsdt: <http://www.w3.org/2001/XMLSchema#>.
@prefix : <http://schemas.bigbank.com/banking#> .

:Account a owl:Class.
     :accountNumber rdfs:domain :Account; rdfs:range xsdt:string.
     :customerName rdfs:domain :Account; rdfs:range xsdt:string.
     :balance rdfs:domain :Account; rdfs:range xsdt:decimal.
     :state rdfs:domain :Account; rdfs:range xsdt:string.

That describes the things an "Account" has.

Next, I created a data file for my data. If ontologies are the XSD, this is the XML. Both of these files use the N3 format, which I guess is some kind of standard way of defining stuff that isn't as much of a pain as XML?

@prefix bank: <http://schemas.bigbank.com/banking#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .

bank:Account_10000000 rdf:type bank:Account ;
     bank:accountNumber "10000000";
     bank:customerName "Paul Stovell";
     bank:balance "10";
     bank:state "SA" .

bank:Account_10000001 rdf:type bank:Account ;
     bank:accountNumber "10000001";
     bank:customerName "Russell Crowe";
     bank:balance "120";
     bank:state "NSW" .

bank:Account_10000002 rdf:type bank:Account ;
     bank:accountNumber "10000002";
     bank:customerName "Chris Judd";
     bank:balance "-10";
     bank:state "WA" .

My client is going to send SPARQL queries, which I understand is a standard query language over the data in these ontologies. On the ASP.NET side, we'll need an HTTP handler which will accept the SPARQL query (which is just an HTTP POST) and execute it against our data store. Fortunately, Andrew's getting started guide points out a free one we can use. I just edit my web.config:

<configuration>
     <configSections>
           <section name="sparqlSources" type="System.Configuration.NameValueSectionHandler, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
...
     <sparqlSources>
           <add key="/BankService.aspx" value="n3:D:\Projects\Local Sandbox\BigBank\BigBank.Server\BankData.n3" />
     </sparqlSources>
...
           <httpHandlers>
                 <remove verb="*" path="*.asmx"/>
                 <add verb="*" path="/BankService.aspx" type="SemWeb.Query.SparqlProtocolServerHandler, SemWeb.Sparql"/>

That's the server defined – I now have a web service that allows me to query for any information around bank accounts. Now to define the client.

In my console application, I add a reference to the LINQ to RDF DLL, and create a strongly typed class to describe the objects I'm querying:

using LinqToRdf;

[assembly: Ontology(Prefix = "bank", BaseUri = "http://schemas.bigbank.com/banking#", Name = "Bank", UrlOfOntology = @"file:///D:/Projects/Local Sandbox/BigBank/BigBank.Server/BankData.owl")]

namespace BigBank.Client
{
   [OwlResource(OntologyName = "Bank", RelativeUriReference = "Account")]
   public class Account
   {
       [OwlResource(OntologyName = "Bank", RelativeUriReference = "accountNumber")]
       public string AccountNumber { get; set; }

       [OwlResource(OntologyName = "Bank", RelativeUriReference = "customerName")]
       public string CustomerName { get; set; }

       [OwlResource(OntologyName = "Bank", RelativeUriReference = "balance")]
       public decimal Balance { get; set; }

       [OwlResource(OntologyName = "Bank", RelativeUriReference = "state")]
       public string State { get; set; }
   }
}

Now I can write strongly typed LINQ queries, which are translated using LINQ to RDF into SPARQL queries, send over the wire in an HTTP request, and executed on the server. Incredible!

Here's the client:

static void Main(string[] args)
{
   TripleStore bankingTrippleStore = new TripleStore("http://localhost:16287/BankService.aspx");
   bankingTrippleStore.QueryType = QueryType.RemoteSparqlStore;

   var allAccounts = from account in new RdfDataContext(bankingTrippleStore).ForType<Account>()
                     where account.State == "NSW"
                     select account;

   Console.WriteLine("The following accounts are in NSW");
   Console.WriteLine("Account number".PadLeft(20) + "Balance".PadLeft(20) + "Customer name".PadLeft(20));
   foreach (Account account in allAccounts)
   {
       Console.WriteLine(account.AccountNumber.PadLeft(20) + account.Balance.ToString("c").PadLeft(20) + account.CustomerName.PadLeft(20));
   }

   Console.ReadKey();
}

And the output:

[cid:image0...@01C8C8B4.BCFAF150]

Here's the HTTP POST data that goes over the web:

PREFIX bank: <http://schemas.bigbank.com/banking#>
PREFIX fn: <http://www.w3.org/2005/xpath-functions#>
PREFIX xsdt: <http://www.w3.org/2001/XMLSchema#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>

SELECT  ?AccountNumber ?CustomerName ?Balance ?State $account
WHERE {
$account a bank:Account.
OPTIONAL{$account bank:accountNumber ?AccountNumber.}
OPTIONAL{$account bank:customerName ?CustomerName.}
OPTIONAL{$account bank:balance ?Balance.}
OPTIONAL{$account bank:state ?State.}
FILTER( regex(?State, "NSW")  )
}


This is really, really awesome. WCF just gives me a way to write the same old web services I've always written in a new way. RDF, SPARQL and LINQ to RDF make me see web services in an entirely new way.

I think I need to step back and understand some of the technologies in play here and the roles they serve – I understand RDF and SPARQL are all about subject/predicate/object, but I'm probably still approaching it in an object-oriented way. I'm really impressed at how far ahead you are Andrew, and I'm sorry I never took time to dig into the project until now.

Regards,
Paul Stovell
Readify | Senior Developer
Microsoft MVP: Visual Developer - Client Application Development

Reply all
Reply to author
Forward
0 new messages