Entity Framework: table without primary key
Asked Answered
S

20

189

I have an existing DB with which I would like to build a new app using EF4.0

Some tables do not have primary keys defined so that when I create a new Entity Data Model, I get the following message:

The table/view TABLE_NAME does not have a primary key defined and no valid primary key could be inferred. This table/view has been excluded. To use the entity, you will need to review your schema, add the correct keys, and uncomment it.

If I want to use them and modify data, must I necessarily add a PK to those tables, or is there a workaround so that I don't have to?

Sensationalism answered 22/10, 2010 at 12:32 Comment(8)
To quote Joe Celko: if it doesn't have a primary key, it's not a table. Why on earth would anyone create a "regular" table without a primary key?? Just add those PK! You'll need them - rather sooner than later....Outwards
If its a view this hava a look this case https://mcmap.net/q/137052/-cannot-add-view-to-the-edmxBollen
If there are no unique columns, you could always add an identity column and make it the PK.Gollin
It's perfectly valid that not every table needs a primary key. Not often useful, but valid. Confusing EF is one good reason, not that it takes much. ;-).Unsearchable
Imagine that I can't modify the DB structure on my company and it was created by somebody that wont change the table structure, this scenario is possible.Houseboat
This is exactly where we are at. We have to work with a 3rd party Oracle database that has no primary keys.Lolitaloll
Fact tables in data warehousing are examples of tables that may not have any use of a primary key. See this answer https://mcmap.net/q/137053/-why-primary-key-is-not-required-on-fact-table-in-dimensional-modellingLexie
@marc_s, I've seen that quote attributed to Joe Celko before, but I actually fail to find evidence that he actually said it. Can you please help me? Can you provide me the name of the book or blog where he said so? Thank you!Misalliance
O
67

The error means exactly what it says.

Even if you could work around this, trust me, you don't want to. The number of confusing bugs that could be introduced is staggering and scary, not to mention the fact that your performance will likely go down the tubes.

Don't work around this. Fix your data model.

EDIT: I've seen that a number of people are downvoting this question. That's fine, I suppose, but keep in mind that the OP asked about mapping a table without a primary key, not a view. The answer is still the same. Working around the EF's need to have a PK on tables is a bad idea from the standpoint of manageability, data integrity, and performance.

Some have commented that they do not have the ability to fix the underlying data model because they're mapping to a third-party application. That is not a good idea, as the model can change out from under you. Arguably, in that case, you would want to map to a view, which, again, is not what the OP asked.

Obbard answered 22/10, 2010 at 12:39 Comment(21)
Agree in common senarios but in rare senarios like LOG table you just need to insert records ASAP. Having PK can be an issue when checking uniqueness and indexing happens. Also If your PK is IDENTITY so returning the generated value to the EF is another issue. using GUID instead? generation time and indexing/sorting is another issue!...SO IN some critical OLTP senarios(like Logging) having no PK is a point and having it has not any positive point!Brannen
@MahmoudMoravej: First off, don't mix up the ideas of clustering indexes and primary keys. They aren't the same thing. You can have very highly performant inserts on tables with clustered indicies on IDENTITY columns. If you run into issues with index maintenance, you should partition the table properly. Leaving a table with no clustered index also means that you can't defragment it effectively to reclaim space after deletes. I pity the poor person who tries to query your logging table if it has no indexes.Obbard
Thanks Dave, you made me to rethink :-) .I didn't know that we can have non-clustered PKs (Although its performance is less than clusterd-one in uniqueness check,isn't it?. specially in IDENTITY PK when the new insert will be put at the end of table space).Brannen
You can have a non-clustered PK, and I often do in certain cases. For example, in logging situations, my PK might be an IDENTITY, but my clustered index will often be on the Time, since clustering by Time speeds up range scans. It's often a good idea to partition such tables by Time as well. In this way, you can choose to only do index maintenance and scans (as needed) on the latest partition. As far as insert performance goes, you're correct in that inserts can be faster with unindexed tables, but querying is much slower.Obbard
"Fix your data model" isn't a real answer. Sometimes we have to live with less-than-ideal situations we did not create and cannot change. And, as @Change said, there IS a way to do exactly what the OP was asking.Agrostology
Changing the code to satisfy EF is a workaround in itself. Not all tables need a primary key nor they should be forced to. E.g. you've a Topic and it has 0 or many keywords. The keywords table can have a parent topic id and a corresponding keyword. TO say that I need to remodel my DB becasue EF forces me to is lame.Tullius
@Mrchief: You most certainly can have a composite primary key in that scenario, where the TopicID and the keyword together comprise the PK of the table.Obbard
I can, but then I'll have to live with the overhead of indexing/maintaining/[checking for uniqueness while inserting a new row] for the composite primary key which is uncalled for. A composite index is also slower and bulkier than having an index on just the userId field, which doesn't have to be unique.Tullius
And its not just EF, I think nHiberante also has this limitation. This is an edge case but not so much. And I really feel this is one of those cases where using a tool becomes an impediment rather than a help.Tullius
So they keep making one mistake after another? Of course, inserting primary key to every table is the the solution to all their problems!Tullius
Sometimes adding a primary key to the schema is not a solution, like when the data is actually a view into a linked server. There might be a non-null field that EF can't recognize. Colin's solution works.Chubby
@Tim: Not sure what you mean by "not a solution". Having a production, non-staging, permanent table without at least one candidate key is always a problem, so choosing an appropriate candidate key is by definition always a solution. To the downvoters out there, feel free to downvote this, but the OP asked about a Table, not a view. And to that specific question, this answer remains the best advice.Obbard
Your answer is accepted and deserves it. I was not only using a view to get the data, I was getting it from a COTS application whose schema I did not control. While I personally prefer to have all PKs and FKs declared in the database, I don't have that freedom in this situation, even on the base tables. In that case, Colin has a solution that will still work. I believe both answers are valuable contributions.Chubby
This should be downvoted because it doesn't answer the question. We often need to work with third party databases that cannot be changed.Gelatinate
@DaveMarkle it's remarkable you have 70k reputation and this kind of attitude. You don't know every situation and there are valid exceptions to every rule. I'm replacing a crap piece of software from CSC that has no PKs and no FKs. It's insane. But long story short, I can depend on no schema changes until the replacement is built but I can't change the schema myself. So the question "can I query the data with EF somehow?" is still valid. Just answer the bleeping question! And obviously the answer isn't "NO" since others have posted a viable solution.Mid
@pbarranis: Generally I would recommend against writing new EF based applications off of a database which is in such a bad state. The best advice in the OP's scenario is to specify a primary key, and not to do the workaround. That might not be the best advice for your particular situation. Chances are, however, that if your database is of nontrivial size and it has no candidate keys defined, a nontrivial EF-based application will suffer some nasty performance problems if you continue down this path. I wish you good luck.Obbard
@DaveMarkle oh no, you couldn't pay me enough to write a new "application" (meaning something long-term and not throw-away) on a DB without PKs and FKs. I'm writing a very simple console app to import the data once so the old CSC app can be given the boot.Mid
What if one wants read-only access? The need for a PK is obvious for adding and updating data and maintaining integrity, but is is really necessary for read-only?Understandable
Conforming to EF6 is not the same as conforming to SQL server (etc). The answer is still valid, but you can't honestly agree it's the correct decision without precluding yourself from all other factors. I wish the answer was instead "here's how you do it", rather than "don't do it". But it's not.Honourable
-1 because this is a classic case of a sort of inverted X/Y problem: the question is specifically: how do I do this without adding a PK. This answer says, "add a PK".Sunburst
@Ben Collins: As an analogy: “How do I wire an electrical outlet with this lamp cord I have? I really don’t want to go to the hardware store and get the right wire.” Sometimes, the only answer is simply, “You don’t. You go to the hardware store and get the right wire.” Yes, you could wire an outlet with a lamp cord and yes it probably wouldn’t burn the house down and yes the question could be answered directly to do the job, but it still wouldn’t be the “right” answer.Obbard
C
106

I think this is solved by Tillito:

Entity Framework and SQL Server View

I'll quote his entry below:

We had the same problem and this is the solution:

To force entity framework to use a column as a primary key, use ISNULL.

To force entity framework not to use a column as a primary key, use NULLIF.

An easy way to apply this is to wrap the select statement of your view in another select.

Example:

SELECT
  ISNULL(MyPrimaryID,-999) MyPrimaryID,
  NULLIF(AnotherProperty,'') AnotherProperty
  FROM ( ... ) AS temp

answered Apr 26 '10 at 17:00 by Tillito

Change answered 4/10, 2011 at 22:5 Comment(5)
+1 This is the right answer, in a perfect world it would be great to go in and modify all legacy databases to have referential integrity, but in reality that's not always possible.Chairwoman
I wouldn't recommend this. Paricularly the ISNULL part. If EF detects two PKs the same, it might not render the unique record(s), and instead return a shared object. This has happened to me before.Asleyaslope
@Todd -- how could that ever happen if MyPrimaryID is a NOT NULL column?Tila
@JoeCool, just because it's NOT NULL doesn't mean it IS unique. I upvoted "THIS SOLUTION WORKS...", because not matter what context it's used in, you can be assured uniqueness. Although thinking about it now, if a record is deleted that will effectively change the following records' "PK".Asleyaslope
-1, because this doesn't answer how to configure Entity Framework/C# code to deal with how to map to a table that lacks an identity seed. Some 3rd party software is (for some reason) written this way.Encephalomyelitis
O
67

The error means exactly what it says.

Even if you could work around this, trust me, you don't want to. The number of confusing bugs that could be introduced is staggering and scary, not to mention the fact that your performance will likely go down the tubes.

Don't work around this. Fix your data model.

EDIT: I've seen that a number of people are downvoting this question. That's fine, I suppose, but keep in mind that the OP asked about mapping a table without a primary key, not a view. The answer is still the same. Working around the EF's need to have a PK on tables is a bad idea from the standpoint of manageability, data integrity, and performance.

Some have commented that they do not have the ability to fix the underlying data model because they're mapping to a third-party application. That is not a good idea, as the model can change out from under you. Arguably, in that case, you would want to map to a view, which, again, is not what the OP asked.

Obbard answered 22/10, 2010 at 12:39 Comment(21)
Agree in common senarios but in rare senarios like LOG table you just need to insert records ASAP. Having PK can be an issue when checking uniqueness and indexing happens. Also If your PK is IDENTITY so returning the generated value to the EF is another issue. using GUID instead? generation time and indexing/sorting is another issue!...SO IN some critical OLTP senarios(like Logging) having no PK is a point and having it has not any positive point!Brannen
@MahmoudMoravej: First off, don't mix up the ideas of clustering indexes and primary keys. They aren't the same thing. You can have very highly performant inserts on tables with clustered indicies on IDENTITY columns. If you run into issues with index maintenance, you should partition the table properly. Leaving a table with no clustered index also means that you can't defragment it effectively to reclaim space after deletes. I pity the poor person who tries to query your logging table if it has no indexes.Obbard
Thanks Dave, you made me to rethink :-) .I didn't know that we can have non-clustered PKs (Although its performance is less than clusterd-one in uniqueness check,isn't it?. specially in IDENTITY PK when the new insert will be put at the end of table space).Brannen
You can have a non-clustered PK, and I often do in certain cases. For example, in logging situations, my PK might be an IDENTITY, but my clustered index will often be on the Time, since clustering by Time speeds up range scans. It's often a good idea to partition such tables by Time as well. In this way, you can choose to only do index maintenance and scans (as needed) on the latest partition. As far as insert performance goes, you're correct in that inserts can be faster with unindexed tables, but querying is much slower.Obbard
"Fix your data model" isn't a real answer. Sometimes we have to live with less-than-ideal situations we did not create and cannot change. And, as @Change said, there IS a way to do exactly what the OP was asking.Agrostology
Changing the code to satisfy EF is a workaround in itself. Not all tables need a primary key nor they should be forced to. E.g. you've a Topic and it has 0 or many keywords. The keywords table can have a parent topic id and a corresponding keyword. TO say that I need to remodel my DB becasue EF forces me to is lame.Tullius
@Mrchief: You most certainly can have a composite primary key in that scenario, where the TopicID and the keyword together comprise the PK of the table.Obbard
I can, but then I'll have to live with the overhead of indexing/maintaining/[checking for uniqueness while inserting a new row] for the composite primary key which is uncalled for. A composite index is also slower and bulkier than having an index on just the userId field, which doesn't have to be unique.Tullius
And its not just EF, I think nHiberante also has this limitation. This is an edge case but not so much. And I really feel this is one of those cases where using a tool becomes an impediment rather than a help.Tullius
So they keep making one mistake after another? Of course, inserting primary key to every table is the the solution to all their problems!Tullius
Sometimes adding a primary key to the schema is not a solution, like when the data is actually a view into a linked server. There might be a non-null field that EF can't recognize. Colin's solution works.Chubby
@Tim: Not sure what you mean by "not a solution". Having a production, non-staging, permanent table without at least one candidate key is always a problem, so choosing an appropriate candidate key is by definition always a solution. To the downvoters out there, feel free to downvote this, but the OP asked about a Table, not a view. And to that specific question, this answer remains the best advice.Obbard
Your answer is accepted and deserves it. I was not only using a view to get the data, I was getting it from a COTS application whose schema I did not control. While I personally prefer to have all PKs and FKs declared in the database, I don't have that freedom in this situation, even on the base tables. In that case, Colin has a solution that will still work. I believe both answers are valuable contributions.Chubby
This should be downvoted because it doesn't answer the question. We often need to work with third party databases that cannot be changed.Gelatinate
@DaveMarkle it's remarkable you have 70k reputation and this kind of attitude. You don't know every situation and there are valid exceptions to every rule. I'm replacing a crap piece of software from CSC that has no PKs and no FKs. It's insane. But long story short, I can depend on no schema changes until the replacement is built but I can't change the schema myself. So the question "can I query the data with EF somehow?" is still valid. Just answer the bleeping question! And obviously the answer isn't "NO" since others have posted a viable solution.Mid
@pbarranis: Generally I would recommend against writing new EF based applications off of a database which is in such a bad state. The best advice in the OP's scenario is to specify a primary key, and not to do the workaround. That might not be the best advice for your particular situation. Chances are, however, that if your database is of nontrivial size and it has no candidate keys defined, a nontrivial EF-based application will suffer some nasty performance problems if you continue down this path. I wish you good luck.Obbard
@DaveMarkle oh no, you couldn't pay me enough to write a new "application" (meaning something long-term and not throw-away) on a DB without PKs and FKs. I'm writing a very simple console app to import the data once so the old CSC app can be given the boot.Mid
What if one wants read-only access? The need for a PK is obvious for adding and updating data and maintaining integrity, but is is really necessary for read-only?Understandable
Conforming to EF6 is not the same as conforming to SQL server (etc). The answer is still valid, but you can't honestly agree it's the correct decision without precluding yourself from all other factors. I wish the answer was instead "here's how you do it", rather than "don't do it". But it's not.Honourable
-1 because this is a classic case of a sort of inverted X/Y problem: the question is specifically: how do I do this without adding a PK. This answer says, "add a PK".Sunburst
@Ben Collins: As an analogy: “How do I wire an electrical outlet with this lamp cord I have? I really don’t want to go to the hardware store and get the right wire.” Sometimes, the only answer is simply, “You don’t. You go to the hardware store and get the right wire.” Yes, you could wire an outlet with a lamp cord and yes it probably wouldn’t burn the house down and yes the question could be answered directly to do the job, but it still wouldn’t be the “right” answer.Obbard
P
37

If I want to use them and modify data, must I necessarily add a PK to those tables, or is there a workaround so that I don't have to?

For those reaching this question and are using Entity Framework Core, you no longer need to necessarily add a PK to thoses tables or doing any workaround. Since EF Core 2.1 we have a new feature Query Types

Query types must be used for:

  • Serving as the return type for ad hoc FromSql() queries.
  • Mapping to database views.
  • Mapping to tables that do not have a primary key defined.
  • Mapping to queries defined in the model.

So in your DbContext just add the following property of type DbQuery<T> instead of DbSet<T> like below. Assuming your table name is MyTable:

public DbQuery<MyTable> MyTables { get; set; }
Polythene answered 30/5, 2018 at 10:13 Comment(1)
Best answer if you are using EF Core!Somite
G
20

Composite keys can also be done with Entity Framework Fluent API

public class MyModelConfiguration : EntityTypeConfiguration<MyModel>
{
     public MyModelConfiguration()
     {
        ToTable("MY_MODEL_TABLE");
        HasKey(x => new { x.SourceId, x.StartDate, x.EndDate, x.GmsDate });
        ...
     }
}
Gynecologist answered 18/11, 2016 at 14:42 Comment(1)
In this sort of 'manual mapping' case, I found that specifying a custom key as you show is effective; additionally, if you don't have the benefit of a composite key (as shown in this answer) you can tag a modelBuilder.Entity<T>() chain-call with .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None) for those oh-so-special keys that aren't natural or composite, but able to be relied upon to be unique (usually, anyways.)Encephalomyelitis
P
9

In EF Core 5.0, you will be able to define it at entity level also.

[Keyless]
public class Address
{
    public string Street { get; set; }
    public string City { get; set; }
    public int Zip { get; set; }
}

Reference: https://learn.microsoft.com/en-us/ef/core/what-is-new/ef-core-5.0/whatsnew#use-a-c-attribute-to-indicate-that-an-entity-has-no-key

Photography answered 12/6, 2020 at 8:34 Comment(1)
This needs to be the top answer. [Keyless] above the class definition works perfectly!! Thank you! One of the top answers says to use DbQuery instead of DbSet. That causes the table to be null.Bloem
S
5

In my case I had to map an entity to a View, which didn't have primary key. Moreover, I wasn't allowed to modify this View. Fortunately, this View had a column which was a unique string. My solution was to mark this column as a primary key:

[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
[StringLength(255)]
public string UserSID { get; set; }

Cheated EF. Worked perfectly, no one noticed... :)

Spallation answered 11/2, 2014 at 1:18 Comment(3)
no.. It will create the UserID column if you using the Code First approach..!Beekeeper
You have not cheated EF. You just commanded to switch off Itentity function. Basically, if I'm correct, It's still going to create UserID column for you as PK but it will not automatically increase the UserID when you create a new record as would be by default. Also, you still need to keep distinct values in UserID.Wilford
@Wilford UserSID is a string, it would never get "automatically increased". If it was an integer identity column then the database would increment it on insert, not Entity Framework.Carrie
R
4

EF does not require a primary key on the database. If it did, you couldn't bind entities to views.

You can modify the SSDL (and the CSDL) to specify a unique field as your primary key. If you don't have a unique field, then I believe you are hosed. But you really should have a unique field (and a PK), otherwise you are going to run into problems later.

Erick

Repossess answered 22/10, 2010 at 20:20 Comment(1)
This avoids the ISNULL hack. But depending on the situation, other answers may be required - I have a feeling that some data types are not supported for a PK in EF for example.Asleyaslope
M
4

Having a useless identity key is pointless at times. I find if the ID isn't used, why add it? However, Entity is not so forgiving about it, so adding an ID field would be best. Even in the case it's not used, it's better than dealing with Entity's incessive errors about the missing identity key.

Mister answered 28/8, 2012 at 17:42 Comment(0)
M
3

THIS SOLUTION WORKS

You do not need to map manually even if you dont have a PK. You just need to tell the EF that one of your columns is index and index column is not nullable.

To do this you can add a row number to your view with isNull function like the following

select 
    ISNULL(ROW_NUMBER() OVER (ORDER BY xxx), - 9999) AS id
from a

ISNULL(id, number) is the key point here because it tells the EF that this column can be primary key

Maragretmarala answered 5/4, 2013 at 12:19 Comment(2)
I wouldn't suggest the ISNULL part though. If EF detects two PKs the same it might not render the unique record, and instead return a shared object. This has happened to me before.Asleyaslope
You have to use isnull, otherwise EF will not beleve that it is not nullable.Philemon
C
3

This is just an addition to @Erick T's answer. If there is no single column with unique values, the workaround is to use a composite key, as follows:

[Key]
[Column("LAST_NAME", Order = 1)]
public string LastName { get; set; }

[Key]
[Column("FIRST_NAME", Order = 2)]
public string FirstName { get; set; }

Again, this is just a workaround. The real solution is to fix the data model.

Courtney answered 9/9, 2016 at 11:18 Comment(0)
R
3

This maybe to late to reply...however...

If a table does't have a primary key then there are few scenarios that need to be analyzed in order to make the EF work properly. The rule is: EF will work with tables/classes with primary key. That is how it does tracking...

Say, your table 1. Records are unique: the uniqueness is made by a single foreign key column: 2. Records are unique: the uniqueness are made by a combination of multiple columns. 3. Records are not unique (for the most part*).

For scenarios #1 and #2 you can add the following line to DbContext module OnModelCreating method: modelBuilder.Entity().HasKey(x => new { x.column_a, x.column_b }); // as many columns as it takes to make records unique.

For the scenario #3 you can still use the above solution (#1 + #2) after you study the table (*what makes all records unique anyway). If you must have include ALL columns to make all records unique then you may want to add a primary key column to your table. If this table is from a 3rd party vendor than clone this table to your local database (overnight or as many time you needed) with primary key column added arbitrary through your clone script.

Rhodic answered 9/7, 2017 at 11:55 Comment(0)
N
2

The above answers are correct if you really don't have a PK.

But if there is one but it is just not specified with an index in the DB, and you can't change the DB (yes, i work in Dilbert's world) you can manually map the field(s) to be the key.

Novelette answered 22/10, 2010 at 14:50 Comment(0)
Q
2

Update to @CodeNotFound's answer.

In EF Core 3.0 DbQuery<T> has been deprecated, instead you should use Keyless entity types which supposedly does the same thing. These are configured with the ModelBuilder HasNoKey() method. In your DbContext class, do this

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder
        .Entity<YourEntityType>(eb =>
        {
            eb.HasNoKey();
        });

}

There are restrictions though, notably:

  • Are never tracked for changes in the DbContext and therefore are never inserted, updated or deleted on the database.
  • Only support a subset of navigation mapping capabilities, specifically:
    • They may never act as the principal end of a relationship.
    • They may not have navigations to owned entities
    • They can only contain reference navigation properties pointing to regular entities.
    • Entities cannot contain navigation properties to keyless entity types.

This means that for the question of

If I want to use them and modify data, must I necessarily add a PK to those tables, or is there a workaround so that I don't have to?

You cannot modify data this way - however you can read. One could envision using another way (e.g. ADO.NET, Dapper) to modify data though - this could be a solution in cases where you rarely need to do non-read operations and still would like to stick with EF Core for your majority cases.

Also, if you truly need/want to work with heap(keyless) tables - consider ditching EF and use another way to talk to your database.

Quagga answered 3/3, 2020 at 16:21 Comment(0)
C
1
  1. Change the Table structure and add a Primary Column. Update the Model
  2. Modify the .EDMX file in XML Editor and try adding a New Column under tag for this specific table (WILL NOT WORK)
  3. Instead of creating a new Primary Column to Exiting table, I will make a composite key by involving all the existing columns (WORKED)

Entity Framework: Adding DataTable with no Primary Key to Entity Model.

Custard answered 29/4, 2012 at 18:5 Comment(2)
I tried the composite key approach with EF 4.0 and it didn't work.Odometer
This approach worked perfectly for me, can be a pain working with legacy systems "sometimes"...Postnasal
W
1

You can have a composite key setup (similar to how VIEWS are done in EF), and apply both key and column order to the fields so that the combination is unique, EF doesn't need a PK (only useful, if doing insert, update or delete operations) to start with, here's an example of a recent implementation:

[Key]
[Column(Order = 0)]
public int NdfID { get; set; }

[Key]
[Column(Order = 1)]
public int? UserID { get; set; }

[Key]
[Column(Order = 2)]
public int ParentID { get; set; }

In this example, my userid field does contain nulls but with the combination of these three all rows are now unique.

Edited this after years :)

Wellheeled answered 21/1, 2014 at 13:32 Comment(0)
C
1

I learned my lesson by working around it. The short answer is DO NOT work around it.

I used EF6 to read a table without a PK but having a compound key. Multiple rows with the same compound key would have the exactly same record. Essentially only one row has been read but used to fill all rows. Since there were million records and it only occurred for a relatively small amount of records which made it very difficult to find the issue.

Colpotomy answered 8/5, 2021 at 11:51 Comment(0)
C
0

From a practical standpoint, every table--even a denormalized table like a warehouse table--should have a primary key. Or, failing that, it should at least have a unique, non-nullable index.

Without some kind of unique key, duplicate records can (and will) appear in the table, which is very problematic both for ORM layers and also for basic comprehension of the data. A table that has duplicate records is probably a symptom of bad design.

At the very least, the table should at least have an identity column. Adding an auto-generating ID column takes about 2 minutes in SQL Server and 5 minutes in Oracle. For that extra bit of effort, many, many problems will be avoided.

Clow answered 6/12, 2013 at 14:57 Comment(1)
My application is in a data warehouse setting (with Oracle) and you convinced me to go through the 5 minutes to add an index. It really only takes 5 minutes (or slightly more if you need to look it up or modify ETLs).Allbee
C
0

We have a table without a unique ID column. Other columns were expected to create a composite key, but over time the data has sometimes not had values in all composite key columns.

Here is a solution using the .NET Entity Framework:

[Key]
[Column(Order = 1)]
public Guid FakeId { get; set; }
public ... other columns

And change the SQL to select this:

SELECT NEWID() as FakeId, ... other columns
Confutation answered 7/9, 2021 at 15:14 Comment(0)
P
0

Late answer here. If you can add a Key - you should. EntityFramework uses it internally. I've seen issues - If you have 2 or more identical rows, it'll only come back once. If that's not an option, You need to make an in-memory composite key. You can do this via the Fluent API in the DbContext or in the class mapping.

Option #1:
In your DbContext to make an in-memory composite key with the Fluent API:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
        modelBuilder.Entity<YOUR_TABLE>()
            .HasKey(c => new { c.Column1, c.Column2, c.Column3, etc. });
}

Option #2:
Same thing but with attributes in EF Object Mapping.

 public class TableName
{
    [Key]
    [Column(Order = 0)]
    public int Column1 { get; set; }
    
    [Key]
    [Column(Order = 1)]
    public int? Column2 { get; set; }
    
    [Key]
    [Column(Order = 2)]
    public int Column3 { get; set; }
}

Option #3:
If you're in EF Core 3.0+ use the fluent API:

modelBuilder
    .Entity<YourEntityType>(eb =>
    {
        eb.HasNoKey();
    });

Option #5:
If you're in EF Core 5.0+ you can do it directly in the EF Object Mapping

[Keyless]
public class TableName
{
    [Key]
    [Column(Order = 0)]
    public int Column1 { get; set; }
    
    [Key]
    [Column(Order = 1)]
    public int? Column2 { get; set; }
    
    [Key]
    [Column(Order = 2)]
    public int Column3 { get; set; }
}
Pyoid answered 9/7, 2023 at 22:29 Comment(0)
H
-8

The table just needs to have one column that does not allow nulls

Harman answered 12/6, 2012 at 20:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.