# Object Identity and Object References

## Introduction

In Starcounter, an object reference uses an implicit foreign key to an implicit primary key called `ObjectId` as well as allowing natural keys and public keys to exist and be joined on when needed.

## Object Identity

Each object has a `ObjectNo` and `ObjectID` property that can be accessed using SQL or the extension methods `Object.GetObjectNo()` and `Object.GetObjectID()`.

`ObjectNo` is a unique `ulong` that can be treated as a primary key. The value becomes available when a database object is created, and is never changed.

`ObjectID` is a [URL Base64](https://en.wikipedia.org/wiki/Base64#URL_applications) string representation of `ObjectNo`. It's friendly for sending over the Internet. For example, `ObjectID` for `ObjectNo=40023` is `"JxX"`. `ObjectID` may contain `[A-Za-z0-9-_]` characters. Since string comparison in SQL is case insensitive, SQL queries using `ObjectID` may return more than one result.

## Primary Keys and Foreign Keys

As each object already has a unique key in `ObjectNo`, we recommend adding other keys when you need them, such as public keys that are meant to be exposed to the end user. Objects should be referenced using an object reference rather than by a foreign key except if there is a clear need for natural key referencing.

## Retrieving from Object Identity

Objects are retrieved from identity with `Db.FromId`. It handles both `ObjectID` and `ObjectNo`.

A common use is in handlers like this where `Person` is a database object:

```csharp
Handle.GET("PersonList/{?}", (string objectId) =>
{
    return new PersonPage()
    {
        Data = Db.FromId<Person>(objectId)
    };
});
```

There are four overloads of `Db.FromId`:

```csharp
T Db.FromId<T>(string base64Id);
T Db.FromId<T>(ulong id);
IObjectView FromId(ulong id);
IObjectView FromId(string base64Id);
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.starcounter.io/2.3.2/guides/database/object-identity-and-object-references.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
