• User Guide
  • API Documentation
  • Tools
  • Developer Guide
  • Support
  • User Guide
  • Getting Started
  • Building SPARQL
Show / Hide Table of Contents
  • Getting Started
    • Core Concepts
    • Hello World
    • Reading RDF
    • Writing RDF
    • Working with Graphs
    • Typed Values and Lists
    • Working with Triple Stores
    • Building SPARQL
    • Querying with SPARQL
    • Updating with SPARQL
    • Formats Supported
    • dotNetRdf Assembly Signing
  • Going Deeper
    • Exceptions
    • Event Model
    • Equality and Comparison
    • Utility Methods
    • Extension Methods
    • Namespace Mapper
    • URI Factory
    • Node Factory
  • Storage API
    • Triple Store Integration
    • Servers API
    • Transactions API
  • Storage Providers
    • Allegro Graph
    • Blazegraph
    • Dataset Files
    • 4store
    • Fuseki
    • In-Memory
    • Sesame
    • SPARQL Query Endpoints
    • SPARQL Query and Update Endpoints
    • SPARQL Graph Store Protocol
    • Stardog
  • Advanced SPARQL
    • Result Formatting
    • SPARQL Datasets
    • Full Text Querying with SPARQL
    • Advanced SPARQL Operations
  • Ontology API
  • Inference and Reasoning
  • Dynamic API
  • Formatting API
  • Configuration API
    • Graphs
    • Triple Stores
    • Object Factories
    • Readers and Writers
    • SPARQL Endpoints (Deprecated)
    • SPARQL Clients
    • Query Processors
    • Update Processors
    • SPARQL Datasets
    • SPARQL Expression Factories
    • SPARQL Operators
    • SPARQL Optimisers
    • Full Text Query
    • Reasoners
    • Storage Providers
    • Static Options
    • Proxy Servers
  • Handlers API
  • JSON-LD API
    • Expansion
    • Compaction
    • Flattening
    • Framing
    • Processor Options
    • Error Handling
  • How-To Guides
    • Debug HTTP Communication
    • Debug SPARQL Queries
    • Load OWL
    • Load RDF from a File
    • Load RDF from the Web
    • Minimize Memory Usage
    • Reify Triples
  • Upgrading to dotNetRDF 3.0
    • Key Changes
    • Global Options Changes

Building SPARQL

SPARQL is the standard query language for the Semantic Web and can be used to query large volumes of RDF data. SPARQL Query Language Specification defines the syntax and semantics of the language and explains SPARQL query buildling with numerous examples. SPARQL standard is drafted and maintained by W3C.

dotNetRDF facilitates SPARQL construction with a set of APIs under VDS.RDF.Query.Builder namespace. We'll look at some of the common queries patterns you can construct using dotNetRDF.

Hello World

Constructing a simple "Hello World" SPARQL. This query fetches all users whose last name is "John Smith"

 SELECT ?x
 WHERE { ?x <http://www.w3.org/2001/vcard-rdf/3.0#FN>  "John Smith" }
using System;
using VDS.RDF.Query.Builder;

static void HelloWorld()
{
	string x = "x";
	var queryBuilder =
		QueryBuilder
		.Select(new string[] { x })
		.Where(
			(triplePatternBuilder) =>
			{
				triplePatternBuilder
					.Subject(x)
					.PredicateUri(new Uri("http://www.w3.org/2001/vcard-rdf/3.0#FN"))
					.Object("John Smith");
			});

	Console.WriteLine(queryBuilder.BuildQuery().ToString());
}

PREFIX with multiple triples

The query fetches given names for the family name "Smith".

PREFIX vcard:      <http://www.w3.org/2001/vcard-rdf/3.0#>

SELECT ?givenName
WHERE
{ 
	?y vcard:Family "Smith" .
	?y vcard:Given ?givenName .
}
using System;
using VDS.RDF;
using VDS.RDF.Query;
using VDS.RDF.Query.Builder;

static void WithPrefix()
{
	var prefixes = new NamespaceMapper(true);
	prefixes.AddNamespace("vcard", new Uri("http://www.w3.org/2001/vcard-rdf/3.0#"));

	string y = "y";
	var givenName = new SparqlVariable("givenName");
	var queryBuilder =
		QueryBuilder
		.Select(new SparqlVariable[] { givenName })
		.Where(
			(triplePatternBuilder) =>
			{
				triplePatternBuilder
					.Subject(y)
					.PredicateUri("vcard:Family")
					.Object("Smith");
				triplePatternBuilder
					.Subject(y)
					.PredicateUri("vcard:Given")
					.Object(givenName);
			});
	queryBuilder.Prefixes = prefixes;

	Console.WriteLine(queryBuilder.BuildQuery().ToString());
}

Numeric FILTER

This query filters resources above 24 years of age.

PREFIX info: < http://somewhere/peopleInfo#>

SELECT ?resource
WHERE
{
	?resource info:age ?age .
	FILTER(?age >= 24)
}
using System;
using VDS.RDF;
using VDS.RDF.Query;
using VDS.RDF.Query.Builder;

static void WithNumericFilter()
{
	var prefixes = new NamespaceMapper(true);
	prefixes.AddNamespace("info", new Uri("http://somewhere/peopleInfo#"));

	string resource = "resource";
	string age = "age";
	var queryBuilder =
		QueryBuilder
		.Select(new string[] { resource })
		.Where(
			(triplePatternBuilder) =>
			{
				triplePatternBuilder
					.Subject(resource)
					.PredicateUri($"info:{age}")
					.Object(age);
			})
		.Filter((builder) => builder.Variable(age) > 24);
	queryBuilder.Prefixes = prefixes;

	Console.WriteLine(queryBuilder.BuildQuery().ToString());
}

Regex FILTER

This query filters given names based on a case-insensitive regex comparison.

PREFIX vcard: <http://www.w3.org/2001/vcard-rdf/3.0#>

SELECT ?g
WHERE
{
	?y vcard:Given ?g .
	FILTER regex(?g, "sarah", "i")
}
using System;
using VDS.RDF;
using VDS.RDF.Query;
using VDS.RDF.Query.Builder;

static void WithRegexFilter()
{
	var prefixes = new NamespaceMapper(true);
	prefixes.AddNamespace("vcard", new Uri("http://www.w3.org/2001/vcard-rdf/3.0#"));

	var givenName = new SparqlVariable("givenName");
	var queryBuilder =
		QueryBuilder
		.Select(new SparqlVariable[] { givenName })
		.Where(
			(triplePatternBuilder) =>
			{
				triplePatternBuilder
					.Subject("y")
					.PredicateUri("vcard:Given")
					.Object(givenName);
			})
		.Filter((builder) => builder.Regex(builder.Variable("givenName"), "sarah", "i"));
	queryBuilder.Prefixes = prefixes;

	Console.WriteLine(queryBuilder.BuildQuery().ToString());
}

OPTIONAL clause with FILTER

This query fetches name and optional age above 42.

PREFIX info:        <http://somewhere/peopleInfo#>
PREFIX vcard:      <http://www.w3.org/2001/vcard-rdf/3.0#>

SELECT ?name ?age
WHERE
{
	?person vcard:FN  ?name .
	OPTIONAL { ?person info:age ?age . FILTER ( ?age > 42 ) }
}
static void WithOptionalAndFilter()
{
	var prefixes = new NamespaceMapper(true);
	prefixes.AddNamespace("info", new Uri("http://somewhere/peopleInfo#"));
	prefixes.AddNamespace("vcard", new Uri("http://www.w3.org/2001/vcard-rdf/3.0#"));

	string name = "name";
	string age = "age";
	string person = "person";
	var queryBuilder =
		QueryBuilder
		.Select(new string[] { name, age })
		.Where(
			(triplePatternBuilder) =>
			{
				triplePatternBuilder
					.Subject(person)
					.PredicateUri("vcard:FN")
					.Object(name);
			})
		.Optional(
			(optionalBuilder) =>
			{
				optionalBuilder.Where(
					(triplePatternBuilder) =>
					{
						triplePatternBuilder
							.Subject(person)
							.PredicateUri($"info:{age}")
							.Object(age);
					});

				optionalBuilder.Filter((b) => b.Variable(age) > 42);
			});
	queryBuilder.Prefixes = prefixes;

	Console.WriteLine(queryBuilder.BuildQuery().ToString());

UNION

This query unions two triple patterns.

PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX vcard: <http://www.w3.org/2001/vcard-rdf/3.0#>

SELECT ?name
WHERE
{
   { [] foaf:name ?name } UNION { [] vcard:FN ?name }
}
public static void WithUnion()
{
	var prefixes = new NamespaceMapper(true);
	prefixes.AddNamespace("foaf", new Uri("http://xmlns.com/foaf/0.1/"));
	prefixes.AddNamespace("vcard", new Uri("http://www.w3.org/2001/vcard-rdf/3.0#"));

	string name = "name";
	var queryBuilder =
		QueryBuilder
		.Select(new string[] { name })
		.GetQueryBuilder();

	queryBuilder
		.Union(
			(unionBuilder) =>
			{
				unionBuilder.Where(
					(tripleBuilder) =>
				{
					tripleBuilder
					.Subject<IBlankNode>("abc")
					.PredicateUri($"foaf:{name}")
					.Object(name);
				});
			},
			(unionBuilder) =>
			{
				unionBuilder.Where(
					c =>
					{
						c
						.Subject<IBlankNode>("abc")
						.PredicateUri("vcard:FN")
						.Object(name);
					});
			});
	queryBuilder.Prefixes = prefixes;

	Console.WriteLine(queryBuilder.BuildQuery().ToString());
}

ORDER BY

This query orders by name.

PREFIX foaf:   <http://xmlns.com/foaf/0.1/>

SELECT ?name
WHERE { ?x foaf:name ?name }
ORDER BY ?name
static void WithOrderBy()
{
	var prefixes = new NamespaceMapper(true);
	prefixes.AddNamespace("foaf", new Uri("http://xmlns.com/foaf/0.1/"));

	string name = "name";
	var queryBuilder =
		QueryBuilder
		.Select(new string[] { name })
		.Where(
			(triplePatternBuilder) =>
			{
				triplePatternBuilder
					.Subject("x")
					.PredicateUri($"foaf:{name}")
					.Object(name);
			})
		.OrderBy(name);
	queryBuilder.Prefixes = prefixes;

	Console.WriteLine(queryBuilder.BuildQuery().ToString());
}

DISTINCT

This query enforces distinctness on names.

PREFIX foaf:   < http://xmlns.com/foaf/0.1/>
SELECT DISTINCT ?name WHERE { ?x foaf:name? name }
static void WithDistinct()
{
	var prefixes = new NamespaceMapper(true);
	prefixes.AddNamespace("foaf", new Uri("http://xmlns.com/foaf/0.1/"));

	string name = "name";
	var queryBuilder =
		QueryBuilder
		.Select(new string[] { name })
		.Distinct()
		.Where(
			(triplePatternBuilder) =>
			{
				triplePatternBuilder
					.Subject("x")
					.PredicateUri($"foaf:{name}")
					.Object(name);
			});
	queryBuilder.Prefixes = prefixes;

	Console.WriteLine(queryBuilder.BuildQuery().ToString());
}

LIMIT

This query limits the result set to 20.

PREFIX foaf:    <http://xmlns.com/foaf/0.1/>

SELECT ?name
WHERE { ?x foaf:name ?name }
LIMIT 20
static void WithLimit()
{
	var prefixes = new NamespaceMapper(true);
	prefixes.AddNamespace("foaf", new Uri("http://xmlns.com/foaf/0.1/"));

	string name = "name";
	var queryBuilder =
		QueryBuilder
		.Select(new string[] { name })
		.Where(
			(triplePatternBuilder) =>
			{
				triplePatternBuilder
					.Subject("x")
					.PredicateUri($"foaf:{name}")
					.Object(name);
			})
		.Limit(20);
	queryBuilder.Prefixes = prefixes;

	Console.WriteLine(queryBuilder.BuildQuery().ToString());
}

BIND

This query creates a computed column with an alias using BIND.

PREFIX  dc:  <http://purl.org/dc/elements/1.1/>
PREFIX  ns:  <http://example.org/ns#>

SELECT  ?price
WHERE
{  ?x ns:price ?p .
   ?x ns:discount ?discount
   BIND (?p*(1-?discount) AS ?price)
}
static void WithBind()
{
	var prefixes = new NamespaceMapper(true);
	prefixes.AddNamespace("dc", new Uri("http://purl.org/dc/elements/1.1/"));
	prefixes.AddNamespace("ns", new Uri("http://example.org/ns#"));

	string p = "p";
	string x = "x";
	string discount = "discount";
	string price = "price";
	var queryBuilder =
		QueryBuilder
		.Select(price)
		.Where(
			(triplePatternBuilder) =>
			{
				triplePatternBuilder
					.Subject(x)
					.PredicateUri($"ns:{price}")
					.Object(p);
				triplePatternBuilder
					.Subject(x)
					.PredicateUri($"ns:{discount}")
					.Object(discount);
			})
		.Bind((builder) => builder.Variable(p) * (1 - builder.Variable(discount)))
			.As(price);
	queryBuilder.Prefixes = prefixes;

	Console.WriteLine(queryBuilder.BuildQuery().ToString());
}

Term Constraints

This query demonstrates enforcing type constraints on terms.

PREFIX info: < http://somewhere/peopleInfo#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
SELECT ?resource
WHERE
  {
	?resource info:bornafter ?bornafter .
	FILTER(?bornafter >= "1970-01-01T00:00:00.000000"^^xsd:dateTime)
  }
static void WithTermConstraints()
{
	var prefixes = new NamespaceMapper(false);
	prefixes.AddNamespace("info", new Uri("http://somewhere/peopleInfo#"));

	string resource = "resource";
	string bornafter = "bornafter";
	var queryBuilder =
		QueryBuilder
		.Select(new string[] { resource })
		.Where(
			(triplePatternBuilder) =>
			{
				triplePatternBuilder
					.Subject(resource)
					.PredicateUri($"info:{bornafter}")
					.Object(bornafter);
			})
		.Filter((builder) => builder.Variable(bornafter) >= builder.Constant(new DateTime(1970, 1, 1)));
	queryBuilder.Prefixes = prefixes;

	Console.WriteLine(queryBuilder.BuildQuery().ToString());
}
  • Improve this Doc
In This Article
  • Hello World
  • PREFIX with multiple triples
  • Numeric FILTER
  • Regex FILTER
  • OPTIONAL clause with FILTER
  • UNION
  • ORDER BY
  • DISTINCT
  • LIMIT
  • BIND
  • Term Constraints
Back to top Generated by DocFX