Este erro ocorre quando a EF não é possível resolver o PK para a sua entidade. Na maioria dos casos, por entidades simples, EF convenções pode trabalhar fora do PK, mas no seu caso, você está usando uma chave composta, então isso precisa ser configurado. Dependendo de como você o mapeamento de suas entidades e você pode fazer isso em:
- um EDMX
- o DbContext.OnModelCreating
- usando um
EntityTypeConfiguration
declaração
- uso de atributos dentro da própria entidade
Desde que nós não sabemos como suas entidades são configurados, você pode verificar isso como a causa, usando o atributo de abordagem dentro de sua entidade como um teste. Se você estiver usando um EDMX as classes de entidade será gerado, então você vai querer substituir essa configuração dentro do EDMX. (Não pode realmente ajudá-lo lá, porque eu não uso o dang coisas :D )
Provavelmente você terá algo como:
public class CarRentalFields
{
[Column("start_day")]
public DateTime StartDay { get; set; }
[Column("return_date")]
public DateTime ReturnDate { get; set; }
[Column("user_id")]
public int UserId { get; set; }
[Column("car_number")]
public DateTime CarNumber { get; set; }
// ... more columns...
}
Você pode até ter uma [Key]
atributo em um desses campos, tais como CarNumber. Se há um PK mapeada na entidade o problema é que ele não é específico o suficiente para identificar exclusivamente a linha. Quando EF vai para a atualização de uma entidade, está a verificar, e esperar a atualização de apenas uma linha na tabela. Para encontrar mais do que uma linha será afetado de modo de falha.
Acrescentar os atributos para o [Key]
com a ordem da coluna, por isso é reconhecida como uma chave composta.
public class CarRentalFields
{
[Key, Column(Name="start_day", Order=1)]
public DateTime StartDay { get; set; }
[Key, Column(Name="return_date", Order=2)]
public DateTime ReturnDate { get; set; }
[Key, Column(Name="user_id", Order=3)]
public int UserId { get; set; }
[Key, Column(Name="car_number", Order=4)]
public DateTime CarNumber { get; set; }
// ... more columns...
}
Desde que estes 4 colunas são garantidos para ser uma restrição unique na tabela, EF será satisfeito quando apenas uma linha é actualizada quando ele cria é instrução SQL UPDATE.
Note novamente que se isso funcionar e você estiver usando um EDMX, você precisará revisar e modificar as suas EDMX mapeamento para fazer as alterações apropriadas, desde que a entidade de classe pode ser regenerado, perdendo seus atributos extra. (Eu acredito que o gerado classes de entidade a partir de um EDMX tem um comentário de cabeçalho de aviso de que é uma classe gerada, de modo que é um indicador a ter em atenção.)
Atualização:
O meu principal suspeito seria que a tabela, na verdade, não têm uma correspondência PK definido, ou executar uma diferente PK combinação, ou mais provavelmente nenhum PK dada a natureza dos campos. EF pode operado em tabelas que não possuem PK definido, mas exige uma definição de Chave que garante registros pode ser identificado exclusivamente. O erro que você está vendo o que acontece quando a chave de definição não é exclusivo o suficiente. (I. e. se você estiver atualizando o carro 1, e a seleção de uma linha que tem:
car_number = 1, start_day = 2021-11-21, return_day = 2021-11-22, user_id = 0 O problema é que, mais do que uma linha tem essa combinação de base de dados. Se a DB que você está verificando não ter mais de uma linha correspondente, em seguida, a sua aplicação é quase certamente, apontando para um banco de dados diferente do que está a verificar.
Coisas que você pode fazer para verificar isso:
- obter o tempo de execução de seqüência de caracteres de conexão e veja se ele combina a DB está a verificar:
Antes de executar a consulta, adicione o seguinte:
// EF6
var connectionString = db.Database.Connection.ConnectionString;
// EF Core 5
var connectionString = db.Database.GetConnectionString();
- Ter um olhar para os dados que são, na verdade, consultar:
.
var cars = db.CarRentalFields.Where(carNum =>
(carNum.CarNumber == carNumber1 && carNum.ActualReturnDate == null)).ToList();
Enquanto essa consulta pode retornar apenas 1 registro, que não é a causa do problema. O que você quer é o CarNumber, StartDate, ReturnDate, e a id de usuário para este registo:
var car = db.CarRentalFields
.Where(carNum => carNum.CarNumber == carNumber1
&& carNum.ActualReturnDate == null)
.Select(x => new
{
x.CarNumber,
x.StartDay,
x.ReturnDate,
x.UserId
}).Single(); // Expect our 1 record here...
var cars = db.CarRentalFields
.Where(x => x.CarNumber == car.CarNumber
&& x.StartDay == car.StartDay
&& x.ReturnDate == car.ReturnDate
&& x.UserId == car.UserId)
.ToList(); // Get rows that match our returned Key fields.
Estas consultas selecione o assumido PK valores para o carro registro que você significa para atualização, em seguida, procura carros de registros coincidentes com a expectativa de campos-Chave. Meu dinheiro estaria em que, enquanto o topo consulta retorna 1 registo, o fundo consulta retorna duas linhas, o que significa, enquanto apenas 1 registo tem um #nulo ActualReturnDate valor, a sua Chave é não singular o suficiente para o conteúdo desta tabela.