Por várias razões sobre as quais não tenho liberdade de falar, estamos definindo uma exibição em nosso banco de dados do Sql Server 2005 da seguinte forma:
CREATE VIEW [dbo].[MeterProvingStatisticsPoint]
AS
SELECT
CAST(0 AS BIGINT) AS 'RowNumber',
CAST(0 AS BIGINT) AS 'ProverTicketId',
CAST(0 AS INT) AS 'ReportNumber',
GETDATE() AS 'CompletedDateTime',
CAST(1.1 AS float) AS 'MeterFactor',
CAST(1.1 AS float) AS 'Density',
CAST(1.1 AS float) AS 'FlowRate',
CAST(1.1 AS float) AS 'Average',
CAST(1.1 AS float) AS 'StandardDeviation',
CAST(1.1 AS float) AS 'MeanPlus2XStandardDeviation',
CAST(1.1 AS float) AS 'MeanMinus2XStandardDeviation'
WHERE 0 = 1
A idéia é que o Entity Framework crie uma entidade com base nessa consulta, o que faz, mas a gera com um erro que afirma o seguinte:
Aviso 6002: A tabela / exibição 'Keystone_Local.dbo.MeterProvingStatisticsPoint' não possui uma chave primária definida. A chave foi inferida e a definição foi criada como uma tabela / exibição somente leitura.
E decide que o campo CompletedDateTime será a chave primária dessa entidade.
Estamos usando o EdmGen para gerar o modelo. Existe uma maneira de não fazer com que a estrutura da entidade inclua algum campo dessa visão como chave primária?
fonte
Consegui resolver isso usando o designer.
Não precisei alterar minha visão para usar as soluções alternativas ISNULL, NULLIF ou COALESCE. Se você atualizar seu modelo a partir do banco de dados, os avisos reaparecerão, mas desaparecerão se você fechar e reabrir o VS. As alterações feitas no designer serão preservadas e não afetadas pela atualização.
fonte
Concorde com o @Tillito, no entanto, na maioria dos casos, ele prejudicará o otimizador de SQL e não usará índices corretos.
Pode ser óbvio para alguém, mas eu queimei horas resolvendo problemas de desempenho usando a solução Tillito. Digamos que você tenha a tabela:
e sua visão é algo como isto
O otimizador sql não usará o índice ix_customer e executará a verificação de tabela no índice primário, mas se em vez de:
você usa
fará com que o MS SQL (pelo menos 2008) inclua o índice correto no plano.
E se
fonte
Este método funciona bem para mim. Uso ISNULL () para o campo da chave primária e COALESCE () se o campo não deve ser a chave primária, mas também deve ter um valor não anulável. Este exemplo gera um campo de ID com uma chave primária não anulável. Os outros campos não são chaves e têm (Nenhum) como atributo Anulável.
se você realmente não possui uma chave primária, pode falsificá-la usando ROW_NUMBER para gerar uma pseudo-chave que é ignorada pelo seu código. Por exemplo:
fonte
NEWID() as id
, mas é a mesma ideia. E existem casos de uso legítimos - se você tem uma exibição somente leitura, por exemplo. Feio, EF, feio.O atual gerador de Entity Framework EDM criará uma chave composta de todos os campos não nulos na sua exibição. Para obter controle sobre isso, você precisará modificar a exibição e as colunas da tabela subjacente, definindo as colunas como nulas quando não desejar que elas façam parte da chave primária. O oposto também é verdadeiro, como eu descobri, a chave gerada pelo EDM estava causando problemas de duplicação de dados, então tive que definir uma coluna anulável como não anulável para forçar a chave composta no EDM a incluir essa coluna.
fonte
Context.Entity.ToList()
registros duplicados, mas se você executar a Consulta SQL gerada pelo EF diretamente (obtida com o LINQPad), nenhuma duplicação de registro ocorrerá. Parece ser um problema ao mapear os registros do banco de dados para os objetos de entidade (POCO) retornados, pois a PK é inferida usando a lógica explicada (colunas não anuláveis).Parece que é um problema conhecido com o EdmGen: http://social.msdn.microsoft.com/forums/en-US/adodotnetentityframework/thread/12aaac4d-2be8-44f3-9448-d7c659585945/
fonte
Para obter uma visualização, eu tinha que mostrar apenas uma coluna de chave primária. Criei uma segunda visualização que apontava para a primeira e usei NULLIF para tornar os tipos anuláveis. Isso funcionou para eu fazer a EF pensar que havia apenas uma única chave primária na exibição.
Não tenho certeza se isso irá ajudá-lo, já que não acredito que a EF aceite uma entidade sem chave primária.
fonte
Se você não quiser mexer com a chave primária, recomendo:
ROW_NUMBER
em sua seleçãofonte
Devido aos problemas mencionados acima, prefiro funções de valor de tabela.
Se você tem isso:
crie isso:
Então você simplesmente importa a função e não a vista.
fonte