Search code examples
c#virtuosodotnetrdf

dotNetRdf Method UpdateGraph not successful with Virtuoso server


I have a Virtuoso-Server on a linux machine (I "inherited" it, so I did not set it up myself). I also inherited the OntoWiki frontend connected to the server to manipulate the data. As this is a bit clumsy and very manual, I wrote a C# project to access and display the data. I access the data using dotNetRdf. Reading is no problem, but now I also want to update the data, thus using the UpdateGraph method. To test this, I wrote a small test-project, after this example from the dotNetRdf-Website: https://github.com/dotnetrdf/dotnetrdf/wiki/UserGuide-Triple-Store-Integration#updategraph

This is my implementation.

VirtuosoManager _virtuosoManager = new VirtuosoManager(ServerAddress, ServerPort, VirtuosoManager.DefaultDB, _user, _password);
string _graphName = "http://od.fmi.uni-leipzig.de/example";

Graph _graph = new Graph();
_virtuosoManager.LoadGraph(_graph, _graphName);

INode s = _graph.CreateUriNode(new Uri(_graphName + "/test"));
INode p = _graph.CreateUriNode(new Uri(RdfSpecsHelper.RdfType));
INode o = _graph.CreateUriNode(new Uri("http://example.org/Example"));
Triple t = new Triple(s, p, o);

_virtuosoManager.UpdateGraph(_graphName, new List<Triple>() { t }, null);

This code runs with no error, but alas also without any update in the graph (which I check with the follwing SPARQL-Request)

SELECT * WHERE {GRAPH ?g {<http://od.fmi.uni-leipzig.de/example/test> ?p ?o .}}

which returns nothing.

So, I changed the log-level on the server, to see how/if the server receives my request. I found the following lines on the logfile:

...
15:47:16 CSLQ_0 109 xxx.xxx.xxx.xxx 1113:2 s1113_2_1 SPARQL define output:format '_JAVA_' INSERT DATA
INTO <http://od.fmi.uni-leipzig.de/example>
{
  <http://od.fmi.uni-leipzig.de/example/test> a <http://example.org/Example> .
}

15:47:16 COMP_2 109 xxx.xxx.xxx.xxx 1113:2 Compile text:  SPARQL define output:format '_JAVA_' INSERT 
DATA
INTO <http://od.fmi.uni-leipzig.de/example>
{
  <http://od.fmi.uni-leipzig.de/example/test> a <http://example.org/Example> .
}

15:47:16 EXEC_1 109 xxx.xxx.xxx.xxx 1113:2 s1113_2_1 Exec 1 time(s) SPARQL define output:format 
'_JAVA_' INSERT DATA
 INTO <http://od.fmi.uni-leipzig.de/example>
{
  <http://od.fmi.uni-leipzig.de/example/test> a <http://example.org/Example> .
}

Looks like my request arives and is computed. Still, the triple is missing. Do you have any idea, what to check / change with the request or the server to make it work?

UPDATE: There is another method called "Update" for the VirtuosoManager of dotNetRdf, where you can send a SPARQL-Query to the Endpoint. So I tried it with the SPARQL-Query from the Server-Log:

string query = "INSERT DATA " + Environment.NewLine +
               "INTO <http://od.fmi.uni-leipzig.de/example>" + Environment.NewLine +
               "{" + Environment.NewLine +
                 "<http://od.fmi.uni-leipzig.de/example/test> a <http://example.org/Example> ." + Environment.NewLine +
               "}";

_virtuosoManager.Update(query);

and the triple is inserted to the database! So it seems to be a problem of (my usage of) the UpdateGraph() method of dotNetRdf. So, I have a kind of a workaround, but I would prefer to omit the error-prone Triple=>SPARQL conversion and leave that to the professionals of dotNetRdf (who probably do this within the UpdateGraph() method).

And this is the server log for the request:

13:45:58 CSLQ_0 109 xxx.xxx.xxx.xxx 1113:2 s1113_2_0 SPARQL INSERT DATA 
INTO <http://od.fmi.uni-leipzig.de/example>
{
<http://od.fmi.uni-leipzig.de/example/test> a <http://example.org/Example> .
}
13:45:58 COMP_2 109 xxx.xxx.xxx.xxx 1113:2 Compile text:  SPARQL INSERT DATA 
INTO <http://od.fmi.uni-leipzig.de/example>
{
<http://od.fmi.uni-leipzig.de/example/test> a <http://example.org/Example> .
}
13:45:58 EXEC_1 109 xxx.xxx.xxx.xxx 1113:2 s1113_2_0 Exec 1 time(s) SPARQL    INSERT DATA 
INTO <http://od.fmi.uni-leipzig.de/example>
{
<http://od.fmi.uni-leipzig.de/example/test> a <http://example.org/Example> .
}

As you can see, the difference is the

define output:format 'JAVA'

for the failing call.

Thanks in advance,
Frank


Solution

  • As answered on the dotNetRDF issue

    The output:format isn't the problem here I think. The issue is that the update transaction is not committed by the code as you have it. The way to do this is to call the Dispose() method on _virtuosoManager. So wrapping your update in a using() block is the best way to go:

    using(var _virtuosoManager = new VirtuosoManager(...)) {
    // Call one or more update methods
    }
    

    Or alternatively you can explicitly call Dispose() (for example if you are going to wrap the manager instance in another class).

    And confirmed by the questioner —

    thank you very much for the reply, it indeed solved my problem! (I used .Dispose())