Skip to content

How to specify PK

Mogens Heller Grabe edited this page Jan 24, 2017 · 5 revisions

By convention, if a property is named Id it will be considered PK of the table and will be used to identify each row when upserting.

For example, this type

class SomeDataRow
{
    public SomeDataRow(int id, decimal number, string text)
    {
        Id = id;
        Number = number;
        Text = text;
    }

    public int Id { get; }
    public decimal Number { get; }
    public string Text { get; }
}

will correspond to the following table schema

CREATE TABLE [dbo].[SomeDataRow] (
	[Id] [int] NOT NULL,
	[Number] [decimal](18, 0) NULL,
	[Text] [nvarchar](256) NULL,
	PRIMARY KEY CLUSTERED 
	(
		[Id] ASC
	)
)

Selecting another property as the ID

If you don't want to have a property named Id on your class, you can specify another ID by decorating a property with the [DebaserKey] attribute, e.g. like so:

class Person
{
    public Person(string ssn, string fullName)
    {
        Ssn = ssn;
        FullName = fullName;
    }

    [DebaserKey]
    public string Ssn { get; }

    public string FullName { get; }
}

which will result in this table schema:

CREATE TABLE [dbo].[Person] (
	[Ssn] [nvarchar](256) NOT NULL,
	[FullName] [nvarchar](256) NULL,
	PRIMARY KEY CLUSTERED 
	(
		[Ssn] ASC
	)
)

Using multiple properties to identify each row

If some cases you want multiple properties in combination to identify each row. While you could accomplish this by concatenating a string or hacking it in other ways, you could also just add the [DebaserKey] attribute multiple times, e.g. like this:

class TenantPerson
{
    public TenantPerson(string tenantId, string ssn, string fullName)
    {
        TenantId = tenantId;
        Ssn = ssn;
        FullName = fullName;
    }

    [DebaserKey]
    public string TenantId { get; }

    [DebaserKey]
    public string Ssn { get; }

    public string FullName { get; }
}

which is a version of the Person model shown before, only scoped by a TenantId so that tenants can have records for the same SSN without interfering. It will result in this table schema:

CREATE TABLE [dbo].[TenantPerson] (
	[TenantId] [nvarchar](256) NOT NULL,
	[Ssn] [nvarchar](256) NOT NULL,
	[FullName] [nvarchar](256) NULL,
	PRIMARY KEY CLUSTERED 
	(
		[TenantId] ASC,
		[Ssn] ASC
	)
)

which does not really come as a surprise at this point 🥇

Clone this wiki locally