Ustawianie jawne wartości dla właściwości wygenerowanegoSetting Explicit Values for Generated Properties

Wygenerowanej właściwości jest właściwością, którego wartość jest generowany (albo przez EF lub baza danych) po dodane lub zaktualizowane jednostki.A generated property is a property whose value is generated (either by EF or the database) when the entity is added and/or updated. Zobacz wygenerowane właściwości Aby uzyskać więcej informacji.See Generated Properties for more information.

Mogą wystąpić sytuacje, w których chcesz ustawić jawną wartość dla wygenerowanej właściwości, zamiast plan wygenerowany.There may be situations where you want to set an explicit value for a generated property, rather than having one generated.

Porada

Można wyświetlić w tym artykule próbki w witrynie GitHub.You can view this article's sample on GitHub.

ModelThe model

Model używany w tym artykule zawiera jeden Employee jednostki.The model used in this article contains a single Employee entity.

public class Employee
{
    public int EmployeeId { get; set; }
    public string Name { get; set; }
    public DateTime EmploymentStarted { get; set; }
    public int Salary { get; set; }
    public DateTime? LastPayRaise { get; set; }
}

Zapisywanie podczas Dodaj jawną wartośćSaving an explicit value during add

Employee.EmploymentStarted Skonfigurowano właściwości do wartości wygenerowanych przez bazę danych dla nowych jednostek (przy użyciu wartości domyślnej).The Employee.EmploymentStarted property is configured to have values generated by the database for new entities (using a default value).

modelBuilder.Entity<Employee>()
    .Property(b => b.EmploymentStarted)
    .HasDefaultValueSql("CONVERT(date, GETDATE())");

Poniższy kod wstawia dwóch pracowników do bazy danych.The following code inserts two employees into the database.

  • W pierwszym nie przypisano żadnej wartości do Employee.EmploymentStarted właściwości, więc pozostaje ustawioną wartość domyślną CLR DateTime.For the first, no value is assigned to Employee.EmploymentStarted property, so it remains set to the CLR default value for DateTime.
  • Dla drugiego, możemy ustawiono jawną wartość 1-Jan-2000.For the second, we have set an explicit value of 1-Jan-2000.
using (var context = new EmployeeContext())
{
    context.Employees.Add(new Employee { Name = "John Doe" });
    context.Employees.Add(new Employee { Name = "Jane Doe", EmploymentStarted = new DateTime(2000, 1, 1) });
    context.SaveChanges();

    foreach (var employee in context.Employees)
    {
        Console.WriteLine(employee.EmployeeId + ": " + employee.Name + ", " + employee.EmploymentStarted);
    }
}

Dane wyjściowe pokazuje, że baza danych wygenerowała wartość dla pierwszej pracownika i użyto naszych jawną wartość dla drugiego.Output shows that the database generated a value for the first employee and our explicit value was used for the second.

1: John Doe, 1/26/2017 12:00:00 AM
2: Jane Doe, 1/1/2000 12:00:00 AM

Jawne wartości w kolumnach tożsamości serwera SQLExplicit values into SQL Server IDENTITY columns

Konwencja Employee.EmployeeId właściwości jest magazynem wygenerowany IDENTITY kolumny.By convention the Employee.EmployeeId property is a store generated IDENTITY column.

W większości sytuacji podejście pokazanym powyżej będzie działać dla właściwości klucza.For most situations, the approach shown above will work for key properties. Jednak aby wstawić jawnej wartości do programu SQL Server IDENTITY kolumnę, musisz ręcznie włączyć IDENTITY_INSERT przed wywołaniem SaveChanges().However, to insert explicit values into a SQL Server IDENTITY column, you need to manually enable IDENTITY_INSERT before calling SaveChanges().

Uwaga

Mamy żądanie funkcji na naszym zaległości się to automatycznie w ramach dostawcy programu SQL Server.We have a feature request on our backlog to do this automatically within the SQL Server provider.

using (var context = new EmployeeContext())
{
    context.Employees.Add(new Employee { EmployeeId = 100, Name = "John Doe" });
    context.Employees.Add(new Employee { EmployeeId = 101, Name = "Jane Doe" });

    context.Database.OpenConnection();
    try
    {
        context.Database.ExecuteSqlCommand("SET IDENTITY_INSERT dbo.Employees ON");
        context.SaveChanges();
        context.Database.ExecuteSqlCommand("SET IDENTITY_INSERT dbo.Employees OFF");
    }
    finally
    {
        context.Database.CloseConnection();
    }


    foreach (var employee in context.Employees)
    {
        Console.WriteLine(employee.EmployeeId + ": " + employee.Name);
    }
}

Dane wyjściowe zawierają, że podane identyfikatory zostały zapisane w bazie danych.Output shows that the supplied ids were saved to the database.

100: John Doe
101: Jane Doe

Ustawienie wartości jawnej podczas aktualizacjiSetting an explicit value during update

Employee.LastPayRaise Skonfigurowano właściwości do wartości wygenerowanych przez bazę danych podczas aktualizacji.The Employee.LastPayRaise property is configured to have values generated by the database during updates.

modelBuilder.Entity<Employee>()
    .Property(b => b.LastPayRaise)
    .ValueGeneratedOnAddOrUpdate();

modelBuilder.Entity<Employee>()
    .Property(b => b.LastPayRaise)
    .Metadata.AfterSaveBehavior = PropertySaveBehavior.Ignore;

Uwaga

Domyślnie EF Core spowoduje zgłoszenie wyjątku, jeśli użytkownik próbuje zapisać jawną wartość dla właściwości, która jest skonfigurowana do wygenerowania podczas aktualizacji.By default, EF Core will throw an exception if you try to save an explicit value for a property that is configured to be generated during update. Aby tego uniknąć, należy rozwinąć niższy poziom metadanych interfejsu API i ustawić AfterSaveBehavior (jak pokazano powyżej).To avoid this, you need to drop down to the lower level metadata API and set the AfterSaveBehavior (as shown above).

Uwaga

Zmiany w programie EF Core 2.0: w poprzednich wersjach zachowanie następującą Zapisz został steruje się za pomocą IsReadOnlyAfterSave flagi.Changes in EF Core 2.0: In previous releases the after-save behavior was controlled through the IsReadOnlyAfterSave flag. Ta flaga zostały zdezaktualizowane i zastępuje AfterSaveBehavior.This flag has been obsoleted and replaced by AfterSaveBehavior.

Istnieje również wyzwalacza w bazie danych do generowania wartości dla LastPayRaise kolumny podczas UPDATE operacji.There is also a trigger in the database to generate values for the LastPayRaise column during UPDATE operations.

CREATE TRIGGER [dbo].[Employees_UPDATE] ON [dbo].[Employees]
	AFTER UPDATE
AS
BEGIN
	SET NOCOUNT ON;
                  
	IF ((SELECT TRIGGER_NESTLEVEL()) > 1) RETURN;
                  
	IF UPDATE(Salary) AND NOT Update(LastPayRaise)
	BEGIN
		DECLARE @Id INT
		DECLARE @OldSalary INT
		DECLARE @NewSalary INT
          
		SELECT @Id = INSERTED.EmployeeId, @NewSalary = Salary        
		FROM INSERTED
          
		SELECT @OldSalary = Salary        
		FROM deleted
          
		IF @NewSalary > @OldSalary
		BEGIN
			UPDATE dbo.Employees
			SET LastPayRaise = CONVERT(date, GETDATE())
			WHERE EmployeeId = @Id
		END
	END
END

Poniższy kod zwiększa wynagrodzenie dwóch pracowników w bazie danych.The following code increases the salary of two employees in the database.

  • W pierwszym nie przypisano żadnej wartości do Employee.LastPayRaise właściwości, więc pozostanie ustawiona na wartość null.For the first, no value is assigned to Employee.LastPayRaise property, so it remains set to null.
  • Dla drugiego możemy ustawiono jawną wartość tydzień temu (Zgłoś uaktualniania płatności wstecz).For the second, we have set an explicit value of one week ago (back dating the pay raise).
using (var context = new EmployeeContext())
{
    var john = context.Employees.Single(e => e.Name == "John Doe");
    john.Salary = 200;

    var jane = context.Employees.Single(e => e.Name == "Jane Doe");
    jane.Salary = 200;
    jane.LastPayRaise = DateTime.Today.AddDays(-7);

    context.SaveChanges();

    foreach (var employee in context.Employees)
    {
        Console.WriteLine(employee.EmployeeId + ": " + employee.Name + ", " + employee.LastPayRaise);
    }
}

Dane wyjściowe pokazuje, że baza danych wygenerowała wartość dla pierwszej pracownika i użyto naszych jawną wartość dla drugiego.Output shows that the database generated a value for the first employee and our explicit value was used for the second.

1: John Doe, 1/26/2017 12:00:00 AM
2: Jane Doe, 1/19/2017 12:00:00 AM