Osy#the first language built for agents
Agents firstAgentic appsWorkflowsDurable Execution — built inSecurityTestingThe editorThe UI modelOne program

Reference / Function

Contains, StartsWith, EndsWith

s.Contains(x) · s.StartsWith(x) · s.EndsWith(x) — ordinal, literal (like C#)

Tests whether a string contains, begins with, or ends with another string. The match is case-sensitive and literal — like C#'s String.Contains, the argument is a plain string, not a pattern. The argument may be a computed value. It gives the same answer whether it runs in the browser, in a function body on the server, or pushed down into a database query.

stable1 example compiled by CIfunctiontextquerysearch

Summary#

s.Contains(x), s.StartsWith(x) and s.EndsWith(x) test a string against another string. They behave exactly like C#'s String.Contains/StartsWith/EndsWith: an ordinal, literal match. They work on a local string and inside a query predicate, and they mean the same thing in both.

Signature#

<string>.Contains(<string>)   -> bool
<string>.StartsWith(<string>) -> bool
<string>.EndsWith(<string>)   -> bool

Description#

The match is literal, not a pattern#

The argument is a plain string. A % or _ in it is an ordinary character — total.Contains("50%") is true only of a string that actually contains "50%". This mirrors C# (and EF Core, which escapes these characters when it translates the call to SQL) — there is no wildcard here.

For a WILDCARD search — % for any run of characters, _ for exactly one — use Text.Like, which is a separate name precisely so the two cannot be confused. It pushes down into a query, and an anchored pattern ("RUSH-%") can use an index.

For full regular expressions on a string you already hold (a validator, a UI action), use Regex. Note it runs in memory only: a regex inside a query .Where(...) predicate does not compile, because it has no SQL form. Inside a query the searches that push down are these three literal tests, Text.Like, and — for a [Searchable] field — full-text .Matches(...).

The match is case-sensitive#

"ACME Ltd".Contains("acme") is false. If you want a case-insensitive search, lower-case both sides:

c.Name.ToLower().Contains("acme")

The argument may be computed#

It does not have to be a literal written in the source — a variable, a parameter, or any expression that yields a string works, in every context:

name.StartsWith(prefix)   // prefix is a parameter, not a literal

One answer, wherever it runs#

The same expression gives the same result whether it is evaluated on a local string in a browser action, in a function body on the server, or compiled into SQL and run by the database. That is not a coincidence — it is the property the three implementations are tested against each other to hold.

Examples#

entity Order { string Code; }

List<Order> RushOrders() {
  return Order.Where(o => o.Code.StartsWith("RUSH-")).ToList();
}

bool MatchesTerm(string note, string term) {
  return note.ToLower().Contains(term.ToLower());   // computed argument; lower BOTH sides to ignore case
}

See also#

  • Text.Like — the WILDCARD search (%, _), which does push down into a query
  • Regex — for full regular expressions on an in-hand string (in memory; not usable in a query predicate)
  • Text.Split — the other string builtins
  • execution side — why this runs in the browser too

Related

Text.Like

Matches a string against a wildcard pattern, where % stands for any run of characters and _ for exactly one. It is the…

Text.Split

The C# string.Split: breaks a string on a separator and returns the substrings as a List<string> — iterable with…

Regex

Match, replace, split and CAPTURE with regular expressions — the C#-faithful System.Text.RegularExpressions spelling…

execution side

Where a function runs. Osy# infers it from the body: a function that reads data runs on the server, a function that…