Pergunta

Eu tenho implementado alguma herança table-per-tipo no meu modelo de dados (basicamente ter um tipo BaseEntity com todas as informações base para meus artigos e um tipo Employer que herda o item BaseEntity). parece que tudo esteja configurado corretamente e quando utilizar as Entidades (via ADO.net Data Services ou através de Linq to Entities) Eu posso ver o tipo Employer e as coisas parecem estar bem. A questão começa quando eu crio uma nova entidade Employer e tentar salvá-lo.

No contexto que não parece ser um item .AddToEmployer (somente e AddObject ou AddToBaseEntity).

Se eu usar AddObject("Employer", NewEmployer) eu recebo e mensagem de erro de:

O nome EntitySet 'DataEntities.Employer' não pôde ser encontrado.

Se eu usar AddToBaseEntity(NewEmployer) eu recebo uma mensagem de erro de:

Não foi possível determinar uma ordenação válida para operações dependentes. Dependências podem existir devido a restrições de chave estrangeira, requisitos modelo orstore gerado valores.

Eu perdi um passo na criação da herança? Existe alguma maneira específica para guardar objetos que são herdados? O que estou fazendo de errado? Presumo que a questão básica é que eu deveria ter um AddToEmployer, o que eu preciso fazer para obter esse exposta? Parece estranho que não é uma opção desde que eu posso ver o tipo Empregador no lado do cliente e pode fazer coisas como:

var NewEmployer = new Employer() -. O que parece sugerir que eu possa ver o tipo Empregador fina

Foi útil?

Solução 3

Eu mudei algumas coisas e foi capaz de chegar a este trabalho. Eu não sou particularmente certo o que era a questão base, mas queria postar o que eu fiz para referência.

Tabelas Reconstruído:. I reconstruída as tabelas começando com apenas o ID / colunas chave e uma coluna de dados único

Removido extras auto incremento campos: eu tinha um ID auto-incremento no BaseEntity e para o empregador. Eu removi o ID auto-incremento para o empregador e só tinha a coluna Employer.BaseEntityID e as costas de chave estrangeira para BaseEntity.BaseEntityID. (Este parece ter sido o culpado, mas eu tinha a impressão isso era permitido)

Infelizmente, este, então, levar para a questão de que as classes enherited no quadro entidade não pode ter propriedades de navegação (todas as propriedades de navegação deve estar na entidade de base), de modo a herança vai revelar-se não-utilizáveis ??para as nossas necessidades.

Outras dicas

Meu nome é Phani e eu trabalho na equipe ADO.NET Data Services.

Os métodos ResolveName e ResolveType são para ajudá-lo a personalizar o tipo de informação que as gravações do cliente na carga enviada para o servidor e como a carga útil resposta do servidor é materializado.

Eles ajudá-lo a resolver os tipos no cliente e são úteis em muitas situações, um par de exemplos são:

  1. A hierarquia tipo de entidades estão em diferentes cliente em comparação com o servidor.
  2. Tipos entidade exposta pelo serviço participar de herança e quer trabalhar com tipos derivados no cliente.

ResolveName é usado para alterar o nome da entidade que colocamos sobre o fio ao fazer um pedido para o servidor.

Considere este modelo de dados: No Servidor

public class Employee {
    public int EmployeeID {get;set;}
    public string EmployeeName {get;set;}
}

public class Manager:Employee {
    public List<int> employeesWhoReportToMe {get;set;}
}

Quando você usa o cliente para trabalhar com instâncias do Gestor de Tipo de Entidade, ao submeter as alterações ao servidor, esperamos informações de tipo para estar presente na carga útil quando as entidades participam de herança.

context.AddObject("Employees",ManagerInstance ); <-- add manager instance to the employees set.
context.SaveChanges();

No entanto, quando o cliente serializa esta carga útil, ele coloca em "Employee", como o nome do tipo o que não é o que se espera no servidor. Daí você tem que fornecer um resolvedor nome no cliente,

context.ResolveName = delegate(Type entityType){
    //do what you have to do to resolve the type to the right type of the entity on the server
    return entityType.FullName;
}

um resolvedor de tipo é usado da mesma forma.

context.ResolveType = delegate(string entitySetName){
    //do what you have to do to convert the entitysetName to a type that the client understands
    return Type.GetType(entitySetName);
}

Bem, você só obter um pr conjunto de entidades. classe de base de modo .AddToBaseEntity é a solução como tal.

Mas parece que você tem uma dependência circular no seu modelo, de modo que a estrutura de entidade não pode descobrir em que ordem para salvar.

Verifique se você tem as chaves estrangeiras para o BaseEntity em suas entidades derivadas e atualizar o seu modelo.

Você não tem Employer definido como conjunto de entidades, assim como o tipo de entidade. Esse é o caminho que está faltando AddToEntity no objeto de contexto. Há sempre um conjunto de entidades para uma hierarquia de classes, neste caso, é ClasseBase conjunto de entidades.

Se você quiser obter conjunto de entidades 'empregador' você pode tentar editar o arquivo edmx manualmente e adicionar novo conjunto de entidades 'empregador' e, em seguida, conjunto de entidades tipo 'empregador' de pertencer a esse conjunto de entidades. Não deve ser difícil, eu tenho feito isso um monte de vezes.

Eu não tenho certeza se existe alguma solução mais regular.

Chegando ao longo de dois anos depois, mas no interesse de mantê-la relevante para o tráfego de busca, aqui está uma maneira que eu trabalhei em torno deste rapidamente em uma classe de conveniência que estávamos usando para rapidamente preencher o nosso banco de dados com encenação de dados.

Não tenho certeza sobre versões anteriores, mas Entity Framework 4 permite despejar o objeto para o contexto como um objeto de base, e depois os números quadro fora as referências do lado do servidor. AddToInheritedObjects Assim, você não utilizados () (que é obsoleto de qualquer maneira), mas sim o método ObjectSet <>. Adicionar ().

Aqui está um exemplo de classe helper:

public ContextHelper
{
        …
        _context = ModelEntities();

        public T Create<T>() where T : class
        {
            // Create a new context
            _context = new ModelEntities();

            // Create the object using the context (can create outside of context too, FYI)
            T obj = _context.CreateObject<T>();

            // Somewhat kludgy workaround for determining if the object is
            // inherited from the base object or not, and adding it to the context's
            // object list appropriately.    
            if (obj is BaseObject)
            {
                _context.AddObject("BaseObjects", obj);
            }
            else
            {
                ObjectSet<T> set = _context.CreateObjectSet<T>();
                set.AddObject(obj);
            }

            return obj;
        }
        …
}

Assim, supondo que você tenha o seguinte:

class ObjectOne : BaseObject {}
class ObjectTwo {}

Você poderia facilmente adicionar entidades ao contexto:

ContextHelper ch = ContextHelper()
ObjectOne inherited = ch.Create<ObjectOne>();
ObjectTwo toplevel = ch.Create<ObjectTwo>();
…

Lembrando, é claro, que ContextHelper deve ter um método público Save () que chama _context.SaveChanges () -. Ou que você deve ter alguma outra forma de empurrar o objeto muda-se para o armazenamento de dados

Isto pode não ser uma resposta direta para qualquer pergunta sobre herança, mas espero que dá às pessoas um ponto de partida para especificidades de respostas.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top