.net 实体框架:没有主键的表
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3996782/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Entity Framework: table without primary key
提问by Cris
I have an existing DB with which I would like to build a new app using EF4.0
我有一个现有的数据库,我想用它来构建一个使用 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".
有些表没有定义主键,所以当我创建一个新的实体数据模型时,我收到以下消息:“表/视图 TABLE_NAME 没有定义主键,无法推断出有效的主键。这张表/视图已被排除。要使用该实体,您需要检查您的架构,添加正确的键,然后取消注释”。
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?
如果我想使用它们并修改数据,我是否必须向这些表添加一个 PK,或者是否有解决方法以便我不必这样做?
采纳答案by Dave Markle
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 tablewithout 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.
编辑:我已经看到很多人对这个问题投反对票。我想这很好,但请记住,OP 询问的是映射没有主键的表,而不是view。答案还是一样。从可管理性、数据完整性和性能的角度来看,解决 EF 需要对表进行 PK 是一个坏主意。
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.
有些人评论说他们没有能力修复底层数据模型,因为它们映射到第三方应用程序。这不是一个好主意,因为模型可能会从你的手下改变。可以说,在这种情况下,您可能希望映射到一个视图,这又不是 OP 所要求的。
回答by Colin
I think this is solved by Tillito:
我认为这是由 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.
要强制实体框架使用列作为主键,请使用 ISNULL。
To force entity framework not to use a column as a primary key, use NULLIF.
要强制实体框架不使用列作为主键,请使用 NULLIF。
An easy way to apply this is to wrap the select statement of your view in another select.
应用它的一个简单方法是将视图的 select 语句包装在另一个 select 中。
Example:
例子:
SELECT
ISNULL(MyPrimaryID,-999) MyPrimaryID,
NULLIF(AnotherProperty,'') AnotherProperty
FROM ( ... ) AS temp
answered Apr 26 '10 at 17:00 by Tillito
Tillito 于 2010 年 4 月 26 日 17:00 回答
回答by CodeNotFound
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?
如果我想使用它们并修改数据,我是否必须向这些表添加一个 PK,或者是否有解决方法以便我不必这样做?
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
对于那些遇到这个问题并正在使用 Entity Framework Core 的人,您不再需要向这些表添加 PK 或执行任何解决方法。从 EF Core 2.1 开始,我们有了一个新功能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.
- 用作临时 FromSql() 查询的返回类型。
- 映射到数据库视图。
- 映射到没有定义主键的表。
- 映射到模型中定义的查询。
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:
因此,在您的 DbContext 中,只需添加以下类型的属性,DbQuery<T>而不是DbSet<T>像下面这样。假设您的表名是MyTable:
public DbQuery<MyTable> MyTables { get; set; }
回答by Adrian Garcia
Composite keys can also be done with Entity Framework Fluent API
复合键也可以使用 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 });
...
}
}
回答by Boris Lipschitz
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:
在我的情况下,我必须将一个实体映射到一个没有主键的视图。此外,我不允许修改此视图。幸运的是,这个 View 有一列是一个唯一的字符串。我的解决方案是将此列标记为主键:
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
[StringLength(255)]
public string UserSID { get; set; }
Cheated EF. Worked perfectly, no one noticed... :)
被骗的EF。完美运行,没有人注意到... :)
回答by Erick T
EF does not require a primary key on the database. If it did, you couldn't bind entities to views.
EF 不需要数据库上的主键。如果是这样,您就无法将实体绑定到视图。
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.
您可以修改 SSDL(和 CSDL)以指定唯一字段作为主键。如果你没有一个独特的领域,那么我相信你已经被灌输了。但是你真的应该有一个独特的领域(和一个PK),否则你以后会遇到问题。
Erick
埃里克
回答by Barny
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.
即使您没有PK,您也不需要手动映射。您只需要告诉 EF 您的其中一列是索引并且索引列不可为空。
To do this you can add a row number to your view with isNull function like the following
为此,您可以使用 isNull 函数向视图添加行号,如下所示
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
ISNULL(id, number)是这里的关键点,因为它告诉 EF 此列可以是主键
回答by IyaTaisho
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.
拥有一个无用的身份密钥有时毫无意义。我发现如果没有使用ID,为什么要添加它?但是,Entity 对此并不那么宽容,因此最好添加一个 ID 字段。即使在不使用它的情况下,也比处理 Entity 有关缺少身份密钥的连续错误要好。
回答by Poker Villain
The above answers are correct if you really don't have a PK.
如果你真的没有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.
但是,如果有一个但它只是没有在数据库中指定索引,并且您无法更改数据库(是的,我在 Dilbert 的世界中工作),您可以手动将字段映射为键。
回答by Developer
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:
这只是@Erick T 答案的补充。如果没有具有唯一值的单个列,则解决方法是使用组合键,如下所示:
[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.
同样,这只是一种解决方法。真正的解决方案是修复数据模型。

