Este artigo foi traduzido por máquina.

Pontos de dados

Perguntas frequentes sobre o Code First e o DbContext do Entity Framework

Julie Lerman

 

Julie LermanEste mês, gostaria de compartilhar as respostas às perguntas que freqüentemente me perguntam sobre código primeiro e DbContext na entidade quadro 4.2. Para maximizar o espaço, eu vou apontar para recursos adicionais onde você pode encontrar informações detalhadas para complementar o material que forneço.

Codificará primeiro e DbContext ser adicionado para o.NET Framework?

Não. Código primeiro e DbContext será distribuído separadamente da Microsoft.NET Framework versão ciclo, permitindo que a equipe do Entity Framework liberar atualizações quando eles estão prontos, sem esperar para o próximo lançamento oficial do.NET Framework. Código primeiro e a API DbContext são parte da Assembleia da EntityFramework.dll, que você pode adicionar aos seus projetos dinamicamente usando o NuGet. Instalando a extensão NuGet no Visual Studio dá-lhe a biblioteca Package Manager, que permite que você adicione uma referência a EntityFramework.dll ao seu projeto. A Figura 1 mostra o pacote de EntityFramework (atualmente o download mais popular na biblioteca de pacote NuGet) no Gerenciador de pacotes de biblioteca do Visual Studio.

Installing Code First and DbContext into a Project via EntityFramework.dll
Figura 1 instalar código primeiro e DbContext em um projeto através de EntityFramework.dll

Você pode ler mais sobre os planos da equipe para liberar recursos do Entity Framework e por que eles decidiram concentrar-se usando o NuGet para a implantação de determinados tipos de recursos fora das.NET APIs em sua postagem no blog de outubro de 2011, "Como podemos falar sobre EF e seu futuro versões" (bit.ly/owoWgn).

Você pode filtrar dados relacionados com incluem?

Não. O método Include permite carregar avidamente dados relacionados ao executar consultas em um modelo de dados de entidade. Infelizmente, você pode recuperar apenas conjuntos de dados relacionados com Carregando ansioso. Isso também é verdadeiro para carregamento lento e, no caso de apenas um, para carregamento explícito. Esse caso único: Quando você carrega explicitamente através o change tracker API, você pode aplicar um método de consulta seguido por uma onde de filtro:

context.Entry(personInstance)
  .Collection(p => p.Aliases)
  .Query()
  .Where(a=>a.FirstName == "Natasha")
  .Load();

Mas para ser claro, você não pode fazer isso para ansioso carregando com incluem.

Isto é como incluir tem trabalhado desde a primeira versão do Entity Framework na.NET Framework 3.5. Se você deseja combinar Carregando ansioso com a filtragem, considere o uso de projeções. Você pode ler mais sobre isso na coluna pontos de dados de Junho de 2011, "Demystifying entidade Framework estratégias: Carregando dados relacionados,"em msdn.microsoft.com/magazine/hh205756. Eu também escrevi um post de blog sobre o tema, "Uso projeções e um repositório para Fake um filtrado ansiosos carga," em bit.ly/uZdnxy.

Como posso usar Lambdas com incluem?

Com o ObjectContext, a única maneira de usar Include está passando uma Cadeia de caracteres para representar a propriedade de navegação a ser ansiosamente carregado. Por exemplo, se você tiver uma classe de estrada que tem uma propriedade, árvores, que é um ICollection <Tree>, seria consulta para estradas com suas árvores como este:

context.Roads.Include("Trees")

Muitos desenvolvedores criaram seus próprios métodos de extensão para permitir-lhes usar uma expressão de rigidez em vez disso:

context.Roads.Include(r => r.Trees)

A capacidade de usar expressões lambda com incluem agora é incorporada a API DbContext. Você encontrará um exemplo de série de blog maravilhoso de 12-parte parte 6 de Arthur Vickers' sobre a API DbContext (bit.ly/wgI5zW). Suas tentativas para usar esse recurso poderiam ter sido mal sucedidas, no entanto — como eram de minas. Eu tive que deixar meu ego de lado e perguntar a alguém da equipe de como obter o suporte de lambda. Acontece que, de uma referência a EntityFramework.dll, você precisa usando uma directiva (ou das importações para o Visual Basic) para System.Data.Entity no arquivo de código onde você está tentando usar Include com um lambda. Se você quiser expandir o ansioso carregando em uma coleção para vários níveis de relações usando os lambdas, você tem que incorporar os métodos de seleção extra. Por exemplo, se sua classe de árvore tem um ICollection <Leaf> e você quer ansioso para carregar as folhas junto com as árvores, a representação de Cadeia de caracteres teria esta aparência:

context.Roads.Include("Trees.Leaves")

No entanto, a lambda depende da lógica adicional para fornecer o nível seguinte da relação. Aqui está a sintaxe que você usaria para selecionar estradas juntamente com as árvores e suas folhas:

context.Roads.Include(r => r.Trees.Select(t => t.Leaves))

Eu não posso falar sobre o uso de vários níveis de inclusão sem adicionar um lembrete de que as relações mais que tentar ansioso carregar com Include, mais complexa e degradado seu query SQL poderia se tornar. Eu sempre recomendo o SQL gerado pela entidade Framework (EF) de criação de perfil. Na verdade, a coluna pontos de dados de Dezembro de 2010 demonstra várias maneiras para o perfil do banco de dados ao usar o EF.

Fiquei surpreso ao saber que se você estiver usando a API de ObjectContext, uma referência ao EntityFramework.dll mais um System.Data.Entity usando diretiva permitirá que você use lambdas com incluir aqui, também.

Eu tenho que esperar para o.NET Framework 4.5 se eu quiser usar código pela primeira vez com os serviços de dados do WCF?

Existem dois módulos (assemblies) para criar e consumir serviços de dados do WCF na.NET Framework 4: System.Data.Services.dll e System.Data.Services.Client.dll. Se você tentar usá-los com um classes DbContext e Code primeiro, eles não funcionarão fora da caixa. O problema é com DbContext, não código primeiro. DbContext não existia quando os assemblies foram construídos, para que eles não entendem isso. Em Março de 2011, a Microsoft lançou uma pré-visualização CTP (Community Technology) que continha fixa-se os assemblies (Microsoft.Data.Services.dll e Microsoft.Data.Services.Client.dll) que sabem como trabalhar com a DbContext. Então tudo que você tem a fazer é substituir os assemblies padrão com estes novos assemblies e, em seus serviços de dados, especificar DataServiceProtocolVersion como V3, em vez de V2. Aqui está um exemplo da aparência que um serviço de dados simples pode expor um contexto (PersonModelContext) que herda de DbContext:

public class DataService : DataService<PersonModelContext>
  {
    public static void InitializeService(DataServiceConfiguration config)
    {
      config.SetEntitySetAccessRule("People", EntitySetRights.All);
      config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3;
    }
}

O problema com esta solução é que os novos assemblies são apenas CTPs e não para fins de produção. Você terá que aguardar o próximo liberado ao Manufacturing (RTM) versão dos serviços de dados para ser capaz de usá-los em produção.

Mas é possível usar um DbContext com.NET Framework 4 System.Data.Services assemblies. Os assemblies CTP existem apenas para ajudá-lo a evitar a escrita de código extra. Tudo que você precisa fazer é acessar o ObjectContext subjacente que suporta a DbContext e que forneça ao serviço. Em julho de 2010, Rowan Miller, um jogador-chave na Microsoft por trás o primeiro código, demonstrou isso em um post do blog, "EF CTP4 Dicas & Truques: Serviço de dados do WCF em DbContext"(bit.ly/c2EA0l). Esse blog foi escrito para uma visualização antecipada do DbContext, assim que eu atualizei o seu exemplo para trabalhar com a versão da classe DbContext na entidade quadro 4.2 usando PersonModelContext, um modelo simples que apresenta um DbSet para uma classe de pessoa. O contexto e a classe são mostrados na Figura 2.

Figura 2 simples DbContext e classe usado por um serviço de dados

public class PersonModelContext : DbContext
{
  public DbSet<Person> People { get; set; }
}
public class Person
{
  public int PersonId { get; set; }
  [MaxLength(10)]
  public string IdentityCardNumber { get; set; }
  public string FirstName { get; set; }
  [Required]
  public string LastName { get; set; }
}

O serviço de dados é definido para funcionar com um ObjectContext, e não especificamente para o PersonModelContext que deriva de DbContext. Em seguida, substituindo os dados de serviço CreateData­método de origem, você pode expor o ObjectContext que sustenta o PersonModelContext, proporcionando a ObjectContext necessária para o serviço, conforme mostrado na Figura 3.

Figura 3 A dados serviço WCF que usa um DbContext com.APIs de serviço do NET Framework 4

public class DataService : DataService<ObjectContext>
{
  public static void InitializeService(DataServiceConfiguration config)
  {
    config.SetEntitySetAccessRule("People", EntitySetRights.All);
    config.DataServiceBehavior.MaxProtocolVersion =
      DataServiceProtocolVersion.V2;
  }
  protected override ObjectContext CreateDataSource()
  {
    var dbContext = new PersonModelContext();
    var oContext = ((IObjectContextAdapter)dbContext).ObjectContext;
    return oContext;
  }
}

Porque eu quero centrar-se sobre o fornecimento de ObjectContext, esta é uma visão simplificada do código que você pode ter no WCF Data Services.

A desvantagem dessa abordagem é que você não será capaz de usar DbContext recursos como validação (como descrito na minha coluna pontos de dados de Dezembro de 2011, "Manipulação entidade Framework validações de dados serviços WCF," em msdn.microsoft.com/magazine/hh580732) porque o serviço é projetado para funcionar com um ObjectContext.

Deve usar anotações de dados ou a API fluente para configurações de primeiras código?

Eu começo pedido esta pergunta muito. Para entender a resposta, é útil entender primeiro as diferenças entre estas duas opções de alto nível.

Código primeiro estende as anotações de dados que são já parte dos.NET Framework 4 System.ComponentModel.DataAnnotations namespace. Além de anotações como ValidationAttributes (obrigatória, StringLength, RegEx), Entity Framework adiciona atributos para especificar mapeamentos do banco de dados (por exemplo, coluna, tabela e Timestamp) ou outros recursos específicos do modelo como ComplexType. As anotações são simples de aplicar em uma classe, como demonstra a classe de pessoa na Figura 2.

Existem algumas possíveis desvantagens usando anotações de dados para configurar suas classes de código primeiro. Uma é que você pode não ser um fã de adicionar lógica de persistência para suas classes de negócios. Se você já se perguntou, "Que o nome de uma coluna de banco de dados tem a ver com o meu modelo de domínio?" você pode não querer usar as anotações de dados. Outra é que esses mapeamentos requerem que você a referência EntityFramework.dll de módulos (assemblies) que contêm as classes de negócio. (Isto muda da.NET Framework 4.5, que irá se apropriar das anotações de dados relacionados com o EF.) Que, também, pode não ser algo que você deseja fazer, especialmente se você estiver distribuir seu aplicativo em camadas. Além disso, as anotações de dados primeiro código não expõem a formação completa de configurações que podem ser aplicados usando código primeiro. Algumas configurações, por exemplo os especificando detalhes particulares para um mapeamento de tabela por hierarquia (TPH), podem ser alcançadas somente usando a API fluente.

Minha recomendação para os desenvolvedores é escolher o estilo que você gosta. Se você preferir ter suas configurações expressas pelos DbContext de Framework de entidade, em seguida, use a API fluente. Se você gostou da simplicidade de aplicar atributos e não me importo com a lógica de mapeamento código primeiro em suas classes, use anotações de dados. Se você optou por usar anotações de dados e se deparar com uma configuração que pode ser expresso apenas com a API fluente, em seguida, adicionar essa configuração fluentemente e usam uma combinação de configurações fluentes e anotações de dados.

Posso usar código pela primeira vez com um banco de dados existente?

Sem dúvida! Embora o comportamento padrão de código primeiro (prestativamente) criar um banco de dados para você, você pode apontar para um banco de dados existente com sua própria Cadeia de caracteres de conexão e ter código primeiro use-o. Existem algumas características internas de código primeiro que permitem que você programaticamente especifique o banco de dados também. Por exemplo, você pode sobrecarregar o Construtor DbContext com um nome de banco de dados ou uma Cadeia de caracteres de conexão do banco de dados. Você pode também especificar e até mesmo personalizar DbContext ConnectionFactory tipos (como SqlConnectionFactory).

Você precisará de assegurar que as convenções de código primeiro, mais quaisquer configurações que você adicionou com precisão representam como suas classes irão mapear para o banco de dados existente. Microsoft tem vindo a trabalhar sobre uma ferramenta que pode reverter a engenharia de um banco de dados em classes mais primeiro código configurações de fluentes, que podem fornecer um grande avanço. Você pode saber mais sobre essa ferramenta no meu post de blog de Maio de 2011, "Quick Look at inverter engenheiro DB em código primeiras aulas" (bit.ly/lHJ2Or).

Ao especificar o local, evite a validação de esquema e a inicialização de banco de dados que DbContext faz por padrão com o primeiro código. Você pode desabilitar completamente esse recurso através do código primeira inicialização de banco de dados:

Database.SetInitializer<MyContext>(null)

Você vai encontrar mais sobre este tema no artigo MSDN Data Developer Center e vídeo, "Inicializadores de banco de dados no Entity Framework 4.1" (msdn.microsoft.com/data/hh272552). Para obter exemplos detalhados de trabalhar com as classes ConnectionFactory e sobrecargas DbContext, ser certo verificar para fora "Programming Entity Framework: Code First"(o ' Reilly Media, 2011), um livro que fui co-autor junto com Rowan Miller da equipe do primeiro código.

Recursos adicionais

Há muitos lugares para aprender sobre como trabalhar com código primeiro e DbContext. Blog da equipe do Entity Framework em blogs.msdn.com/adonet é preenchida com walk-throughs e exemplos. Alguns blogs de membro, como Rowan Miller da equipe (romiller.com) e Arthur Vickers' (blog.oneunicorn.com/author/ajcvickers), são ótimos lugares para ler sobre técnicas avançados. Os fóruns do MSDN e StackOverflow.com continuam a ser grandes lugares para ler tópicos ou fazer suas próprias perguntas. Miller e eu escrevi recentemente dois livros curtos, a referida "Programming Entity Framework: Primeira do código"e" Entity Framework de programação: DbContext"(o ' Reilly Media, 2012). Você pode começ estes em formato digital ou impressão.

Não é necessário lutar com a tentar descobrir coisas fora em seu próprio país.

Julie Lerman é um MVP da Microsoft.NET mentor e consultor que vive nas montanhas de Vermont. Você pode encontrar sua apresentação sobre acesso a dados e outro Microsoft.NET tópicos em grupos de usuários e conferências em todo o mundo. She blogs at thedatafarm.com e é o autor de "Programming Entity Framework" (2010) e "Programming Entity Framework: Code First"(2011), ambos do ' Reilly Media. Siga ela no Twitter em twitter.com/julielerman.

Agradecemos aos seguintes especialistas técnicos pela revisão deste artigo: Mike Flasko e Diego Vega