How can I reference a property to be a ForeignKey plugged to a DB computed field (from a view) ?
I have the following :
public class PersonSite
{
public int Id {get;set;}
//...
public int PersonId {get;set;}
[ForeignKey("PersonId")]
public virtual Person Person {get;set;}
//...
}
public class Person
{
public Id {get;set;}
//...
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public int? MainPersonSiteId { get; protected internal set; }
[ForeignKey("MainPersonSiteId")]
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public PersonSite MainPersonSite { get; protected internal set; }
//...
}
Whenever I try to update a Person
, I get the following excpetion:
Message:
A dependent property in a ReferentialConstraint is mapped to a store-generated column. Column: 'MainPersonSiteId'. Stack trace:
at System.Data.Entity.Core.Mapping.Update.Internal.UpdateCompiler.BuildSetClauses(DbExpressionBinding target, PropagatorResult row, PropagatorResult originalRow, TableChangeProcessor processor, Boolean insertMode, Dictionary`2& outputIdentifiers, DbExpression& returning, Boolean& rowMustBeTouched) at System.Data.Entity.Core.Mapping.Update.Internal.UpdateCompiler.BuildUpdateCommand(PropagatorResult oldRow, PropagatorResult newRow, TableChangeProcessor processor) at System.Data.Entity.Core.Mapping.Update.Internal.TableChangeProcessor.CompileCommands(ChangeNode changeNode, UpdateCompiler compiler)
In the database, which is Sql Server 12, Person comes from a view, where MainPersonSiteId is projected from a function. This is a computed field, which does not need to be updated by the ORM.
How to define it with EntityFramework ?
EDIT :
I just managed to have update working by setting DatabaseGeneratedOption.Identity
instead of DatabaseGeneratedOption.Computed
, nevertheless I just found the inserts were still broken. So I tested the inserts with DatabaseGeneratedOption.Computed
back and it ... worked :/
The situation is :
- I can insert only with DatabaseGeneratedOption.Computed
- I can update only with DatabaseGeneratedOption.Identity
It's strange as MSDN says that DatabaseGeneratedOption.Computed
let the DB generate a value for both inserts and updates while DatabaseGeneratedOption.Identity
does only for inserts
Columns in the database defined as IDENTITY are different from COMPUTED ones.
When you insert a new row, then the database engine creates a new value (number) for an IDENTITY-Column. For example you can use this as a primary/unique key column. You can not update an IDENTITY column. You can't define a formula for doing calculations.
When you want to calculate somethin' at the table level, you can use computed columns. Here you have to define a formula. When you create the computed column with the PERSISTED option, then SQL-Server stores the computed values in the table. When you update columns which are part of a computed column, only then the computed column gets updated. PERSISTED computed columns can be part of index-key-columns and foreign keys. When you don't use the PERSISTED option, the database does not store the computed values. So it has to do the calculation every time a query needs the computed column.
When you update a row, make sure the computed column is not part of list of columns to be updated (in the SET-clause of an UPDATE-statement).
You can define FOREIGN KEYs only between tables and not views.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.