Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optional alternate key properties #4415

Open
Tracked by #22953
BradBarnich opened this issue Jan 27, 2016 · 29 comments
Open
Tracked by #22953

Optional alternate key properties #4415

BradBarnich opened this issue Jan 27, 2016 · 29 comments

Comments

@BradBarnich
Copy link

All of the major relational databases allow null values in unique key constraints.

As a workaround I could use unique indexes instead of alternate keys, but I would appreciate the semantics of a unique key constraint.

Something like this got me around the issue: BradBarnich@c23988e

I can fix it up and submit a PR if you agree this should be fixed.

@rowanmiller rowanmiller changed the title Use of a property in an Alternate Key shouldn't make it required Optional alternate key properties Feb 12, 2016
@rowanmiller rowanmiller added this to the Backlog milestone Feb 12, 2016
@rowanmiller
Copy link
Contributor

Agreed this would be good. Currently EF is built on the assumption that an alternate key is always populated, but we could definitely relax this. Putting on backlog since we won't be doing this for 1.0.0.

@divega
Copy link
Contributor

divega commented Apr 7, 2017

Keywords: nullable alternante keys.

@ajcvickers
Copy link
Member

Note: allowing alternate keys to be nullable is potentially not difficult--from an EF perspective, if an entity has a null alternate key, then it's the same as that entity not existing for any dependents. Note, however that making alternate keys read-write is much more involved.

@divega divega added good first issue This issue should be relatively straightforward to fix. help wanted This issue involves technologies where we are not experts. Expert help would be appreciated. and removed help wanted This issue involves technologies where we are not experts. Expert help would be appreciated. good first issue This issue should be relatively straightforward to fix. labels May 31, 2019
@ajcvickers ajcvickers removed the help wanted This issue involves technologies where we are not experts. Expert help would be appreciated. label Jul 1, 2019
@keatkeat87
Copy link

keatkeat87 commented Feb 1, 2020

@ajcvickers
Today i get this error.
"Unable to track an entity of type 'Demo' because alternate key property 'TestValue' is null. If the alternate key is not used in a relationship, then consider using a unique index instead. Unique indexes may contain nulls, while alternate keys must not."

how if i need to use in a relationship, is it possible or not the right way ?
can give a clear direction for me ?

@buttch
Copy link

buttch commented Apr 2, 2020

Hi,
is there any plan to make it possible to have nullable properties as alternate key ?
I work with legacy system with database which has a lot of strange ideas implemented :(
Suddenly it turned out that in columns which I use for relation are null in same cases.
I need to know if I need to implement workaround or it will be implemented in EF Core.

@ajcvickers
Copy link
Member

@buttch Currently EF can't handle rows with a null principal key value. One workaround is to write your queries such that they filter out any principal entities with null values. That is, manually add a Where clause to do the filtering.

@buttch
Copy link

buttch commented Apr 3, 2020

@ajcvickers Thanks for answer. Unfortunately your workaround it not good for me. This null principal (alternate) key value is in dependent of dependent of dependent of my main entity and I need those entities anyway I cannot filter them out. I think in such case the only way is to load them in separate query and add to entities manually. What do you think ?

@ajcvickers
Copy link
Member

@buttch First, make sure you really need an alternate key in EF terms. You said, "it turned out that in columns which I use for relation are null in same case" which I read to mean that these columns are referenced at the principal end of a relationship. If that's not the case, then configure a unique constraint instead of an alternate key as mentioned in the tip here.

Beyond that, I'm afraid EF can't track entities with null alternate key values. Unfortunately, I can't think of any other workarounds.

@mguinness
Copy link

Please thumbs up the original post so that it has a better chance of being considered in the Plan for Entity Framework Core 5.0.

Your feedback on planning is important. The best way to indicate the importance of an issue is to vote (thumbs-up 👍) for that issue on GitHub. This data will then feed into the planning process for the next release.

@goforgold
Copy link

Hi @BradBarnich

Can you please suggest how exactly you did the workaround?

I have something like this.

builder.Entity<DsOrder>()
        .HasIndex(m => new { m.OrderId, m.ClientId }).IsUnique();

builder.Entity<DsOrderState>()
        .HasOne(m => m.Order).WithMany(m => m.OrderStates).HasForeignKey(m => new { m.ClientId, m.OrderId }).HasPrincipalKey(m => new { m.ClientId, m.OrderId });

My Order entity has OrderId as int? and ClientId + OrderId together are unique. I've not used IsRequired() but still can't get rid of nullable: false in migration. It is always making OrderId in my Order table as not nullable.

Please help!

@Neme12
Copy link

Neme12 commented Dec 9, 2020

Why is this limitation there? 😔 I simply want a unique constraint where a few columns are nullable, but that's OK. It should behave the same way as a unique index without a filter, which it would do if this worked.

@Neme12
Copy link

Neme12 commented Dec 9, 2020

@buttch First, make sure you really need an alternate key in EF terms. You said, "it turned out that in columns which I use for relation are null in same case" which I read to mean that these columns are referenced at the principal end of a relationship. If that's not the case, then configure a unique constraint instead of an alternate key as mentioned in the tip here.

Beyond that, I'm afraid EF can't track entities with null alternate key values. Unfortunately, I can't think of any other workarounds.

@ajcvickers But is there a way to create a unique constraint without an alternate key (as opposed to a unique index)? The documentation you pointed to doesn't show anything like that.

@ajcvickers
Copy link
Member

@Neme12 No. Can you explain why you need it to be a constraint instead of an index? Are you aware of a database that implements a unique constraint and a unique index differently?

@rp0m
Copy link

rp0m commented Feb 24, 2021

So just to confirm, currently, EF Core 3.0 does not support nullable composite foreign keys/alternate keys, correct?

I've got this code in my context, however I still get the foreign key generated as not nullable :(

modelBuilder
	.Entity<EntityOne>()
	.HasOne(x => x.EntityTwo)
	.WithOne(x => x.EntityOne)
	.HasForeignKey<EntityTwo>(x =>
		new
		{
			x.IdOne,
			x.IdTwo
		})
	.IsRequired(false)
	.HasPrincipalKey<EntityOne>(x =>
		new
		{
			x.EntityTwoIdOne,
			x.EntityTwoIdTwo
		});

@ajcvickers
Copy link
Member

@rp0m Nullable foreign keys are supported and commonly used. Alternate keys cannot be nullable.

@reinux
Copy link

reinux commented Jul 25, 2021

It also seems to be assuming that I have an alternate key when I really don't want it to be an alternate key. Not sure how to fix that.

@dillontsmith
Copy link

+1 on requesting this feature. It would be very useful for us.

@jyothi530
Copy link

jyothi530 commented Apr 29, 2022

@ajcvickers EF Core v6.0.3: I am facing some weird issue on an entity with Alternate Key. The AlternateKey column is nullable. When I load the entity along with the AlternateKey navigation property using Include(), the query generated is making an inner join on the AlternateKey navigation table.
If I don't eager load the alternate key navigation property and load just the entity with the data containing null value for AlternateKey it is throwing SqlNullException (Data is Null).

@Neme12
Copy link

Neme12 commented Apr 30, 2022

@ajcvickers

@Neme12 No. Can you explain why you need it to be a constraint instead of an index? Are you aware of a database that implements a unique constraint and a unique index differently?

You're right, I don't need it, I'd just prefer it, and if it was possible, I wouldn't need a separate property as a primary key - I could simply use a composite key from 2 columns where one or both are nullable (and where null should be a unique value too).

@rcreynolds53
Copy link

+1 on requesting this feature highly useful

@wjax
Copy link

wjax commented Feb 13, 2023

+1

@acraven
Copy link

acraven commented Apr 19, 2023

+1, I'm currently migrating a system from NHibernate and I have stumbled upon this problem.

@marchy
Copy link

marchy commented Nov 30, 2023

Can you please tackle this in EF9 as part of the work to support nullable complex types?

Both these features become nearly useless when they can be only applied to non-nullable types/fields. It's a complete disconnect with real domains in the wild, which in practice tend to have MOST fields be nullable / vary by some related attribute, and there is very little you can guarantee will never be null (ie: it's highly academic to design an ORM and the systems they power against such assumptions).

UPDATE: It seems unique indexes don't work with nullable columns either. This really needs to be tackled as a cross-cutting epic: "Make Nullable Columns Work (everywhere)".

@its-jefe
Copy link

Just hit this snag and having nullable alternate keys would be lovely. Looking into workarounds now

@PoteRii
Copy link

PoteRii commented Jul 15, 2024

+1

@ajcvickers ajcvickers removed their assignment Aug 31, 2024
@SeriaWei
Copy link

+1

@enrij
Copy link

enrij commented Sep 18, 2024

+1 for @marchy comment on unique indexes with nulls... I really fell off the chair when i discovered the "autofilter" on non null values while creating an UNIQUE index (better explained by @marchy himself on his link, no kudos for me)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment