Skip to content
Snippets Groups Projects
Commit 22d4fdeb authored by Hanna Führ's avatar Hanna Führ
Browse files

Update: Migrate resource structured data to linked data (coscine/issues#2084)

parent 667e0540
Branches
No related tags found
1 merge request!9New: Migrate resource structured data to linked data
Pipeline #774510 skipped
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
using Coscine.Database.Models; using Coscine.Database.Models;
using Coscine.Configuration; using Coscine.Configuration;
using VDS.RDF; using VDS.RDF;
using VDS.RDF.Query;
namespace SQL2Linked.Implementations namespace SQL2Linked.Implementations
{ {
...@@ -13,53 +14,125 @@ namespace SQL2Linked.Implementations ...@@ -13,53 +14,125 @@ namespace SQL2Linked.Implementations
public readonly Uri acl = new("http://www.w3.org/ns/auth/acl#"); public readonly Uri acl = new("http://www.w3.org/ns/auth/acl#");
public readonly Uri foaf = new("http://xmlns.com/foaf/0.1/"); public readonly Uri foaf = new("http://xmlns.com/foaf/0.1/");
public readonly Uri pim = new("http://www.w3.org/ns/pim/space#"); public readonly Uri pim = new("http://www.w3.org/ns/pim/space#");
public readonly Uri RdfType = new("http://www.w3.org/1999/02/22-rdf-syntax-ns#type"); public readonly Uri rdf = new("http://www.w3.org/1999/02/22-rdf-syntax-ns#");
public readonly Uri cosc = new("https://purl.org/coscine/");
private VisibilityModel VisibilityModel = new VisibilityModel();
private ProjectResourceModel ProjectResourceModel =new ProjectResourceModel();
public override IEnumerable<IGraph> ConvertToLinkedData(IEnumerable<Resource> entries) public override IEnumerable<IGraph> ConvertToLinkedData(IEnumerable<Resource> entries)
{ {
IEnumerable<Visibility> visibilities = VisibilityModel.GetAll();
IEnumerable<ProjectResource> projectResources = ProjectResourceModel.GetAll();
var graphs = new List<IGraph>(); var graphs = new List<IGraph>();
string ResourceUrlPrefix = "https://hdl.handle.org/" + Prefix; string resourceUrlPrefix = "https://hdl.handle.net/" + Prefix;
foreach (var entry in entries) foreach (var entry in entries)
{ {
var resourceTypeGraphName = $"{ResourceUrlPrefix}/{entry.Id}"; var resourceGraphName = $"{resourceUrlPrefix}/{entry.Id}";
//var graphA = RdfStoreConnector.CreateNamedGraph(resourceTypeGraphName);
var graph = RdfStoreConnector.GetGraph(resourceTypeGraphName); var graph = new Graph();
graph.BaseUri = new Uri(resourceGraphName);
/*graph.Assert( AssertToGraphUriNode(graph, resourceGraphName, rdf + "type", dcat + "Catalog");
new Triple( Console.WriteLine($"For resource '{entry.DisplayName}' will migrate triple '{resourceGraphName} {rdf}type {dcat}Catalog'. ");
graph.CreateUriNode(new Uri(resourceTypeGraphName)),
graph.CreateUriNode(RdfType), AssertToGraphUriNode(graph, resourceGraphName, rdf + "type", pim + "Storage");
graph.CreateUriNode(new Uri(dcat, "Catalog")) Console.WriteLine($"For resource '{entry.DisplayName}' will migrate triple '{resourceGraphName} {rdf}type {pim}Storage'. ");
)
);*/ AssertToGraphUriNode(graph, resourceGraphName, dcat + "service", cosc + $"resourcetype/{entry.TypeId}");
AssertToGraphUriNode(graph, resourceTypeGraphName, RdfType, new Uri(dcat + "Catalog")); Console.WriteLine($"For resource '{entry.DisplayName}' will migrate triple '{resourceGraphName} {dcat}service {cosc}resourcetype/{entry.TypeId}'. ");
graphs.Add(graph);
AssertToGraphLiteralNode(graph, resourceGraphName, dcterms + "title", entry.ResourceName);
Console.WriteLine($"For resource '{entry.DisplayName}' will migrate triple '{resourceGraphName} {dcterms}title {entry.ResourceName}'. ");
AssertToGraphLiteralNode(graph, resourceGraphName, dcterms + "alternative", entry.DisplayName);
Console.WriteLine($"For resource '{entry.DisplayName}' will migrate triple '{resourceGraphName} {dcterms}alternative {entry.DisplayName}'. ");
foreach (var visibility in visibilities)
{
if (entry.VisibilityId == visibility.Id && visibility.DisplayName.Contains("Public"))
{
AssertToGraphUriNode(graph, resourceGraphName, cosc + "terms/resource#visibility", cosc + $"terms/vivibility#public");
Console.WriteLine($"For resource '{entry.DisplayName}' will migrate triple '{resourceGraphName} {cosc}terms/resource#visibility {cosc}terms/vivibility#public'. ");
break;
}
else if (entry.VisibilityId == visibility.Id && visibility.DisplayName.Contains("Project Members"))
{
AssertToGraphUriNode(graph, resourceGraphName, cosc + "terms/resource#visibility", cosc + $"terms/vivibility#projectMember");
Console.WriteLine($"For resource '{entry.DisplayName}' will migrate triple '{resourceGraphName} {cosc}terms/resource#visibility {cosc}terms/vivibility#projectMember'. ");
break;
} }
return graphs;
} }
public void AssertToGraphUriNode(IGraph graph, string graphSubject, Uri graphPredicate, Uri graphObject) var listKeywords = entry.Keywords.Split(';').ToList();
foreach (var keyword in listKeywords)
{ {
graph.Assert( AssertToGraphLiteralNode(graph, resourceGraphName, dcterms + "subject", keyword);
new Triple( Console.WriteLine($"For resource '{entry.DisplayName}' will migrate triple '{resourceGraphName} {dcterms}subject {keyword}'. ");
graph.CreateUriNode(new Uri(graphSubject)),
graph.CreateUriNode(graphPredicate),
graph.CreateUriNode(graphObject)
)
);
} }
public void AssertToGraphLiteralNode(IGraph graph, Uri graphSubject, Uri graphPredicate, string graphObject) AssertToGraphLiteralNode(graph, resourceGraphName, dcterms + "rights", entry.UsageRights);
Console.WriteLine($"For resource '{entry.DisplayName}' will migrate triple '{resourceGraphName} {dcterms}rights {entry.UsageRights}'. ");
AssertToGraphLiteralNode(graph, resourceGraphName, dcterms + "description", entry.Description);
Console.WriteLine($"For resource '{entry.DisplayName}' will migrate triple '{resourceGraphName} {dcterms}description {entry.Description}'. ");
AssertToGraphUriNode(graph, resourceGraphName, dcterms + "conformsTo", entry.ApplicationProfile);
Console.WriteLine($"For resource '{entry.DisplayName}' will migrate triple '{resourceGraphName} {dcterms}conformsTo {entry.ApplicationProfile}'. ");
AssertToGraphLiteralNode(graph, resourceGraphName,cosc + "terms/resource#fixedValues", entry.FixedValues);
Console.WriteLine($"For resource '{entry.DisplayName}' will migrate triple '{resourceGraphName} {cosc}terms/resource#fixedValues {entry.FixedValues}'. ");
AssertToGraphUriNode(graph, resourceGraphName, dcterms + "creator", cosc + $"users/{entry.Creator}");
Console.WriteLine($"For resource '{entry.DisplayName}' will migrate triple '{resourceGraphName} {dcterms}creator {cosc}users/{entry.Creator}'. ");
AssertToGraphLiteralNode(graph, resourceGraphName, cosc + "terms/resource#archived", entry.Archived.ToString(), new Uri("http://www.w3.org/2001/XMLSchema#boolean"));
Console.WriteLine($"For resource '{entry.DisplayName}' will migrate triple '{resourceGraphName} {cosc}terms/resource#archived {entry.Archived.ToString()}'. ");
AssertToGraphUriNode(graph, resourceGraphName, foaf + "homepage", resourceGraphName);
Console.WriteLine($"For resource '{entry.DisplayName}' will migrate triple '{resourceGraphName} {foaf}homepage {resourceGraphName}'. ");
SparqlParameterizedString cmdString = new SparqlParameterizedString
{
CommandText = "SELECT DISTINCT ?g " +
"WHERE {" +
"GRAPH ?g { ?s ?p ?o } . " +
"FILTER(STRSTARTS(STR(?s), \"" + resourceGraphName + "@\"))" +
"}"
};
var resultSet = QueryEndpoint.QueryWithResultSet(cmdString.ToString());
foreach(var result in resultSet)
{
AssertToGraphUriNode(graph, resourceGraphName, dcat + "catalog", result[0].ToString());
Console.WriteLine($"For resource '{entry.DisplayName}' will migrate triple '{resourceGraphName} {dcat}catalog {result[0].ToString()}'. ");
}
AssertToGraphUriNode(graph, resourceGraphName, rdf + "type", acl + "Authorization");
Console.WriteLine($"For resource '{entry.DisplayName}' will migrate triple '{resourceGraphName} {rdf}type {acl}Authorization'. ");
foreach (var projectResource in projectResources)
{
if (entry.Id == projectResource.ResourceId)
{ {
AssertToGraphUriNode(graph, resourceGraphName, acl + "agentGroup", $"{resourceUrlPrefix}/{projectResource.ProjectId}");
Console.WriteLine($"For resource '{entry.DisplayName}' will migrate triple '{resourceGraphName} {acl}agentGroup {resourceUrlPrefix}/{projectResource.ProjectId}'. ");
break;
}
}
AssertToGraphUriNode(graph, resourceGraphName, acl + "accessTo", resourceGraphName);
Console.WriteLine($"For resource '{entry.DisplayName}' will migrate triple '{resourceGraphName} {acl}accessTo {resourceGraphName}'. ");
AssertToGraphUriNode(graph, resourceGraphName, acl + "mode", acl + "Control");
Console.WriteLine($"For resource '{entry.DisplayName}' will migrate triple '{resourceGraphName} {acl}accessTo {acl}Control'. ");
graphs.Add(graph);
}
return graphs;
} }
} }
} }
\ No newline at end of file
...@@ -10,7 +10,9 @@ namespace SQL2Linked.Implementations ...@@ -10,7 +10,9 @@ namespace SQL2Linked.Implementations
public readonly Uri RdfType = new("http://www.w3.org/1999/02/22-rdf-syntax-ns#type"); public readonly Uri RdfType = new("http://www.w3.org/1999/02/22-rdf-syntax-ns#type");
public readonly Uri DcatDataService = new ("http://www.w3.org/ns/dcat#DataService"); public readonly Uri DcatDataService = new ("http://www.w3.org/ns/dcat#DataService");
public readonly Uri dctermsTitle = new("http://purl.org/dc/terms/title"); public readonly Uri dctermsTitle = new("http://purl.org/dc/terms/title");
public readonly Uri rdf = new("http://www.w3.org/1999/02/22-rdf-syntax-ns#");
public readonly Uri dcat = new("http://www.w3.org/ns/dcat#");
public readonly Uri dcterms = new("http://purl.org/dc/terms/");
public override IEnumerable<IGraph> ConvertToLinkedData(IEnumerable<ResourceType> entries) public override IEnumerable<IGraph> ConvertToLinkedData(IEnumerable<ResourceType> entries)
{ {
...@@ -22,43 +24,29 @@ namespace SQL2Linked.Implementations ...@@ -22,43 +24,29 @@ namespace SQL2Linked.Implementations
var graph = RdfStoreConnector.GetGraph(resourceTypeGraphName); var graph = RdfStoreConnector.GetGraph(resourceTypeGraphName);
// check if a triple with a dcat:DataService already exists in the resourcetype graph // check if a triple with a dcat:DataService already exists in the resourcetype graph
var getTriplesDcatDataService = graph.GetTriplesWithObject(DcatDataService); var getTriplesDcatDataService = graph.GetTriplesWithObject(new Uri(dcat + "DataService"));
if (!getTriplesDcatDataService.Any()) if (!getTriplesDcatDataService.Any())
{ {
graph.Assert( AssertToGraphUriNode(graph, resourceTypeGraphName, rdf + "type", dcat + "DataService");
new Triple( Console.WriteLine($"For resource type '{entry.DisplayName}' will migrate triple '{graph.BaseUri} {rdf}type {dcat}DataService'. ");
graph.CreateUriNode(new Uri(resourceTypeGraphName)),
graph.CreateUriNode(RdfType),
graph.CreateUriNode(DcatDataService)
)
);
Console.WriteLine($"For resource type '{entry.DisplayName}' will migrate triple '{graph.BaseUri}' a dcat:DataService. ");
} }
else else
{ {
Console.WriteLine($"For resource type '{entry.DisplayName}' will NOT migrate triple '{graph.BaseUri}' a dcat:DataService. "); Console.WriteLine($"For resource type '{entry.DisplayName}' will NOT migrate triple '{graph.BaseUri} {rdf}type {dcat}DataService'. ");
} }
// check if a triple with dcterms:title '{entry.DisplayName}' already exists in the role graph // check if a triple with dcterms:title '{entry.DisplayName}' already exists in the role graph
var getTriplesDctermsTitle = graph.GetTriplesWithPredicate(dctermsTitle); var getTriplesDctermsTitle = graph.GetTriplesWithPredicate(new Uri(dcterms + "Title"));
if (!getTriplesDctermsTitle.Any()) if (!getTriplesDctermsTitle.Any())
{ {
graph.Assert( AssertToGraphLiteralNode(graph, resourceTypeGraphName, dcterms + "title", entry.DisplayName);
new Triple( Console.WriteLine($"For resource type '{entry.DisplayName}' will migrate triple '{graph.BaseUri} {dcterms}title {entry.DisplayName}'. ");
graph.CreateUriNode(new Uri(resourceTypeGraphName)),
graph.CreateUriNode(dctermsTitle),
graph.CreateLiteralNode(entry.DisplayName)
)
);
Console.WriteLine($"For resource type '{entry.DisplayName}' will migrate triple '{graph.BaseUri}' dcterms:title '{entry.DisplayName}'. ");
} }
else else
{ {
Console.WriteLine($"For resource type '{entry.DisplayName}' will NOT migrate triple '{graph.BaseUri}' dcterms:title '{entry.DisplayName}'. "); Console.WriteLine($"For resource type '{entry.DisplayName}' will NOT migrate triple '{graph.BaseUri} {dcterms}title {entry.DisplayName}'. ");
} }
if (!getTriplesDcatDataService.Any() || !getTriplesDctermsTitle.Any()) if (!getTriplesDcatDataService.Any() || !getTriplesDctermsTitle.Any())
{ {
......
...@@ -7,9 +7,10 @@ namespace SQL2Linked.Implementations ...@@ -7,9 +7,10 @@ namespace SQL2Linked.Implementations
public class RoleStructuralData : StructuralData<Role, RoleModel> public class RoleStructuralData : StructuralData<Role, RoleModel>
{ {
public readonly string RoleUrlPrefix = "https://purl.org/coscine/roles"; public readonly string RoleUrlPrefix = "https://purl.org/coscine/roles";
public readonly Uri RdfType = new("http://www.w3.org/1999/02/22-rdf-syntax-ns#type"); public readonly Uri cosc = new("https://purl.org/coscine/");
public readonly Uri orgRole = new("http://www.w3.org/ns/org#Role"); public readonly Uri rdf = new("http://www.w3.org/1999/02/22-rdf-syntax-ns#");
public readonly Uri dctermsTitle = new("http://purl.org/dc/terms/title"); public readonly Uri org = new("http://www.w3.org/ns/org#");
public readonly Uri dcterms = new("http://purl.org/dc/terms/");
public override IEnumerable<IGraph> ConvertToLinkedData(IEnumerable<Role> entries) public override IEnumerable<IGraph> ConvertToLinkedData(IEnumerable<Role> entries)
{ {
...@@ -21,43 +22,29 @@ namespace SQL2Linked.Implementations ...@@ -21,43 +22,29 @@ namespace SQL2Linked.Implementations
var graph = RdfStoreConnector.GetGraph(roleGraphName); var graph = RdfStoreConnector.GetGraph(roleGraphName);
// check if a triple with a org:role already exists in the role graph // check if a triple with a org:role already exists in the role graph
var getTriplesOrgRole = graph.GetTriplesWithObject(orgRole); var getTriplesOrgRole = graph.GetTriplesWithObject(new Uri(org + "Role"));
if (!getTriplesOrgRole.Any()) if (!getTriplesOrgRole.Any())
{ {
graph.Assert( AssertToGraphUriNode(graph, roleGraphName, rdf + "type", org + "Role");
new Triple( Console.WriteLine($"For role '{entry.DisplayName}' will migrate triple '{graph.BaseUri} {rdf}type {org}Role'. ");
graph.CreateUriNode(new Uri(roleGraphName)),
graph.CreateUriNode(RdfType),
graph.CreateUriNode(orgRole)
)
);
Console.WriteLine($"For role '{entry.DisplayName}' will migrate triple '{graph.BaseUri}' a org:Role. ");
} }
else else
{ {
Console.WriteLine($"For role '{entry.DisplayName}' will NOT migrate triple '{graph.BaseUri}' a org:Role. "); Console.WriteLine($"For role '{entry.DisplayName}' will NOT migrate triple '{graph.BaseUri} {rdf}type {org}Role'. ");
} }
// check if a triple with dcterms:title '{entry.DisplayName}' already exists in the role graph // check if a triple with dcterms:title '{entry.DisplayName}' already exists in the role graph
var getTriplesDctermsTitle = graph.GetTriplesWithPredicate(dctermsTitle); var getTriplesDctermsTitle = graph.GetTriplesWithPredicate(new Uri(dcterms + "title"));
if (!getTriplesDctermsTitle.Any()) if (!getTriplesDctermsTitle.Any())
{ {
graph.Assert( AssertToGraphLiteralNode(graph, roleGraphName, dcterms + "title", entry.DisplayName);
new Triple( Console.WriteLine($"For role '{entry.DisplayName}' will migrate triple '{graph.BaseUri} {dcterms}title {entry.DisplayName}'. ");
graph.CreateUriNode(new Uri(roleGraphName)),
graph.CreateUriNode(dctermsTitle),
graph.CreateLiteralNode(entry.DisplayName)
)
);
Console.WriteLine($"For role '{entry.DisplayName}' will migrate triple '{graph.BaseUri}' dcterms:title '{entry.DisplayName}'. ");
} }
else else
{ {
Console.WriteLine($"For role '{entry.DisplayName}' will NOT migrate triple '{graph.BaseUri}' dcterms:title '{entry.DisplayName}'. "); Console.WriteLine($"For role '{entry.DisplayName}' will NOT migrate triple '{graph.BaseUri} {dcterms}title {entry.DisplayName}'. ");
} }
if (!getTriplesOrgRole.Any() || !getTriplesDctermsTitle.Any()) if (!getTriplesOrgRole.Any() || !getTriplesDctermsTitle.Any())
{ {
......
...@@ -8,9 +8,8 @@ namespace SQL2Linked.Implementations ...@@ -8,9 +8,8 @@ namespace SQL2Linked.Implementations
public class UserStructuralData : StructuralData<User, UserModel> public class UserStructuralData : StructuralData<User, UserModel>
{ {
public readonly string UserUrlPrefix = "https://purl.org/coscine/users"; public readonly string UserUrlPrefix = "https://purl.org/coscine/users";
public readonly Uri RdfType = new("http://www.w3.org/1999/02/22-rdf-syntax-ns#type"); public readonly Uri rdf = new("http://www.w3.org/1999/02/22-rdf-syntax-ns#");
public readonly Uri FoafPerson = new("http://xmlns.com/foaf/0.1/Person"); public readonly Uri foaf = new("http://xmlns.com/foaf/0.1/");
public override IEnumerable<IGraph> ConvertToLinkedData(IEnumerable<User> entries) public override IEnumerable<IGraph> ConvertToLinkedData(IEnumerable<User> entries)
{ {
var graphs = new List<IGraph>(); var graphs = new List<IGraph>();
...@@ -21,17 +20,11 @@ namespace SQL2Linked.Implementations ...@@ -21,17 +20,11 @@ namespace SQL2Linked.Implementations
var graph = RdfStoreConnector.GetGraph(userGraphName); var graph = RdfStoreConnector.GetGraph(userGraphName);
// check if a triple with a foaf:Person already exists in the user graph // check if a triple with a foaf:Person already exists in the user graph
var getTriples = graph.GetTriplesWithObject(FoafPerson); var getTriples = graph.GetTriplesWithObject(new Uri(foaf + "Person"));
if (!getTriples.Any()) if (!getTriples.Any())
{ {
graph.Assert( AssertToGraphUriNode(graph, userGraphName, rdf + "type", foaf + "Person");
new Triple(
graph.CreateUriNode(new Uri(userGraphName)),
graph.CreateUriNode(RdfType),
graph.CreateUriNode(FoafPerson)
)
);
graphs.Add(graph); graphs.Add(graph);
......
...@@ -9,7 +9,7 @@ if (dummyMode) ...@@ -9,7 +9,7 @@ if (dummyMode)
Console.WriteLine("\nBegin SQL 2 Linked Data migration"); Console.WriteLine("\nBegin SQL 2 Linked Data migration");
/*var roleStructuralData = new RoleStructuralData(); var roleStructuralData = new RoleStructuralData();
roleStructuralData.Migrate(dummyMode); roleStructuralData.Migrate(dummyMode);
var userStructuralData = new UserStructuralData(); var userStructuralData = new UserStructuralData();
...@@ -18,8 +18,8 @@ userStructuralData.Migrate(dummyMode); ...@@ -18,8 +18,8 @@ userStructuralData.Migrate(dummyMode);
var resourceTypeStructuralData = new ResourceTypeStructuralData(); var resourceTypeStructuralData = new ResourceTypeStructuralData();
resourceTypeStructuralData.Migrate(dummyMode); resourceTypeStructuralData.Migrate(dummyMode);
var projectStructuralData = new ProjectStructuralData(); //var projectStructuralData = new ProjectStructuralData();
projectStructuralData.Migrate(dummyMode);*/ //projectStructuralData.Migrate(dummyMode);
var resourceStructuralData = new ResourceStructuralData(); var resourceStructuralData = new ResourceStructuralData();
resourceStructuralData.Migrate(dummyMode); resourceStructuralData.Migrate(dummyMode);
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
using Coscine.Database.Models; using Coscine.Database.Models;
using Coscine.Metadata; using Coscine.Metadata;
using VDS.RDF; using VDS.RDF;
using VDS.RDF.Query;
namespace SQL2Linked namespace SQL2Linked
{ {
...@@ -11,6 +12,7 @@ namespace SQL2Linked ...@@ -11,6 +12,7 @@ namespace SQL2Linked
public ConsulConfiguration Configuration { get; init; } public ConsulConfiguration Configuration { get; init; }
public RdfStoreConnector RdfStoreConnector { get; init; } public RdfStoreConnector RdfStoreConnector { get; init; }
public static string Prefix { get; set; } public static string Prefix { get; set; }
public readonly SparqlRemoteEndpoint QueryEndpoint;
public StructuralData() public StructuralData()
{ {
...@@ -18,6 +20,7 @@ namespace SQL2Linked ...@@ -18,6 +20,7 @@ namespace SQL2Linked
RdfStoreConnector = new RdfStoreConnector(Configuration.GetStringAndWait("coscine/local/virtuoso/additional/url")); RdfStoreConnector = new RdfStoreConnector(Configuration.GetStringAndWait("coscine/local/virtuoso/additional/url"));
Model = new T(); Model = new T();
Prefix = Configuration.GetStringAndWait("coscine/global/epic/prefix"); Prefix = Configuration.GetStringAndWait("coscine/global/epic/prefix");
QueryEndpoint = new SparqlRemoteEndpoint(new Uri(string.Format("http://localhost:8890/sparql")));
} }
public abstract IEnumerable<IGraph> ConvertToLinkedData(IEnumerable<S> entries); public abstract IEnumerable<IGraph> ConvertToLinkedData(IEnumerable<S> entries);
...@@ -53,5 +56,26 @@ namespace SQL2Linked ...@@ -53,5 +56,26 @@ namespace SQL2Linked
Console.WriteLine(); Console.WriteLine();
} }
} }
public void AssertToGraphUriNode(IGraph graph, string graphSubject, string graphPredicate, string graphObject)
{
graph.Assert(
new Triple(
graph.CreateUriNode(new Uri(graphSubject)),
graph.CreateUriNode(new Uri(graphPredicate)),
graph.CreateUriNode(new Uri(graphObject))
)
);
}
public void AssertToGraphLiteralNode(IGraph graph, string graphSubject, string graphPredicate, string graphObject, Uri? objectType = null)
{
graph.Assert(
new Triple(
graph.CreateUriNode(new Uri(graphSubject)),
graph.CreateUriNode(new Uri(graphPredicate)),
graph.CreateLiteralNode(graphObject, objectType)
)
);
}
} }
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment