2010-09-22 14 views
6

Tengo la siguiente configuración (que funciona bien). Usando CodeFirst (CTP4).Muchas a muchas relaciones sin tablas de unión dobles, Entity Framework

Una plantilla tiene una lista de influencias, cada influencia le da un valor a un rasgo.

public class Template 
{ 
    public virtual int Id { get; set; } 
    public virtual ICollection<Influence> Influences { get; set; } 
} 

public class Influence 
{ 
    public virtual int Id { get; set; } 
    public virtual Trait Trait { get; set; } 
    public virtual int Value { get; set; } 
} 

public class Trait 
{ 
    public virtual int Id { get; set; } 
    public virtual string Name { get; set; } 
} 

La plantilla se configura de esta manera.

public class TemplateConfiguration : EntityConfiguration<Template> 
{ 
    public TemplateConfiguration() 
    { 
     HasKey(o => o.Id); 
     Property(o => o.Id).IsIdentity(); 

     HasMany(o => o.Influences).WithRequired() 
      .Map("templates.influences", 
      (template, influence) => new { 
       Template = template.Id, 
       Influence = influence.Id 
      }); 
     MapSingleType(o => new { 
      o.Id 
     }); 
    } 
} 

Este obras pero prefiero evitar la tabla extra 'influencias'. Esencialmente, 'Influencias' es simplemente un objeto y no es necesario que sea una tienda central para ellos. De hecho, es más beneficioso para el diseño que intento abordar si no existe una mesa central para ellos.

Deseo configurar un escenario como este para la tabla de Plantillas ... Básicamente Influencias no tienen su propia tabla, solo están mapeadas por Rasgo/Valor donde se usan.

public TemplateConfiguration() 
    { 
     HasMany(u => u.Influences).WithMany() 
      .Map("templates.influences", 
      (template, influence) => new { 
       Template = template.Id, 
       Trait = influence.Trait.Id, 
       Value = influence.Value 
      }); 

     MapSingleType(c => new { 
      c.Id 
     }).ToTable("templates"); 
    } 

Cuando intento hacerlo de esta manera, obtengo la excepción en la asignación de plantillas.

System.InvalidOperationException era no controlada

la expresión dada incluye un patrón no reconocido 'influence.Trait.Id'.


A continuación se muestra todo el código del proyecto, si es necesario.

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Data.Objects; 
using System.Data.EntityClient; 
using System.Data.Entity.ModelConfiguration; 
using System.Data.Entity; 
using System.Data.Entity.Infrastructure; 

namespace EFTest 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
        Database.SetInitializer<SampleDataContext>(new AlwaysRecreateDatabase<SampleDataContext>()); 
      var builder = new ModelBuilder(); 

      builder.Configurations.Add(new TraitConfiguration()); 
      builder.Configurations.Add(new InfluenceConfiguration()); 
      builder.Configurations.Add(new TemplateConfiguration()); 

      var model = builder.CreateModel(); 

      using (var context = new SampleDataContext(model)) 
      { 
       var traits = new List<Trait> 
       { 
        new Trait { Name = "Years" }, 
        new Trait { Name = "Days" } 
       }; 
       traits.ForEach(x => { context.Traits.Add(x); }); 
       context.SaveChanges(); 

       var templates = new List<Template> 
       { 
        new Template 
        { 
         Influences = new List<Influence> 
         { 
          new Influence 
          { 
           Trait = context.Traits.Single(i => i.Name == "Years"), 
           Value = 5 
          }, 
          new Influence 
          { 
           Trait = context.Traits.Single(i => i.Name == "Days"), 
           Value = 15 
          } 
         } 
        } 
       }; 
       templates.ForEach(x => { context.Templates.Add(x); }); 
       context.SaveChanges(); 
      } 
     } 
    } 

    public class SampleDataContext : DbContext 
    { 
     public SampleDataContext(DbModel model) 
      : base(model) 
     { 
     } 

     public DbSet<Trait> Traits { get; set; } 
     public DbSet<Influence> Influences { get; set; } 
     public DbSet<Template> Templates { get; set; } 
    } 

    public class Trait 
    { 
     public virtual int Id { get; set; } 
     public virtual string Name { get; set; } 
    } 

    public class TraitConfiguration : EntityConfiguration<Trait> 
    { 
     public TraitConfiguration() 
     { 
      HasKey(o => o.Id); 
      Property(o => o.Id).IsIdentity(); 

      MapSingleType(o => new { 
       o.Id, 
       o.Name 
      }); 
     } 
    } 

    public class Influence 
    { 
     public virtual int Id { get; set; } 
     public virtual Trait Trait { get; set; } 
     public virtual int Value { get; set; } 
    } 

    public class InfluenceConfiguration : EntityConfiguration<Influence> 
    { 
     public InfluenceConfiguration() 
     { 
      HasKey(o => o.Id); 
      Property(o => o.Id).IsIdentity(); 

      HasRequired(o => o.Trait); 
      Property(o => o.Value); 

      MapSingleType(o => new { 
       o.Id, 
       Trait = o.Trait.Id, 
       o.Value 
      }); 
     } 
    } 

    public class Template 
    { 
     public virtual int Id { get; set; } 
     public virtual ICollection<Influence> Influences { get; set; } 
    } 

    public class TemplateConfiguration : EntityConfiguration<Template> 
    { 
     public TemplateConfiguration() 
     { 
      HasKey(o => o.Id); 
      Property(o => o.Id).IsIdentity(); 

      HasMany(o => o.Influences).WithRequired() 
       .Map("templates.influences", 
       (template, influence) => new { 
        Template = template.Id, 
        Influence = influence.Id 
       }); 
      MapSingleType(o => new { 
       o.Id 
      }); 
     } 
    } 
} 
+0

cualquier persona? ¿Por favor? Esto realmente me está volviendo loco. – Ciel

+1

Obtendrás más respuestas si publicas un fragmento de código extremadamente corto y simple que captura el problema en su forma mínima en lugar de la gran cantidad de código que tienes actualmente. Además, cuando dice "me da errores", debe incluir el texto completo de error/excepción; de lo contrario, equivale a decir "no funciona". –

+2

Normalmente, cuando publico solo lo que es necesario, hago que la gente se queje de que no proporciono el código suficiente para que sea útil. Así que esta vez acabo de publicar el proyecto completo. Lo he editado para que sea más conciso, y dejé el código completo en la parte inferior para cualquier referencia necesaria. – Ciel

Respuesta

1

OK, nuevo día new idea.

He instalado CTP4 y obtuve las mismas 4 tablas que tiene.

La razón por la que se produce la relación muchos a muchos, es que el modelo no sabe que una plantilla solo tendrá influencia. Entonces usted tiene que decirle que:

public class Influence 
{ 
    public virtual int Id { get; set; } 
    public virtual Trait Trait { get; set; } 
    public virtual int Value { get; set; } 
    public virtual Template Template { get; set; } 
} 

y:

public InfluenceConfiguration() 
    { 
     HasKey(o => o.Id); 
     Property(o => o.Id).IsIdentity(); 
     Property(o => o.Value); 

     MapSingleType(o => new 
     { 
      o.Id, 
      Trait = o.Trait.Id, 
      o.Value, 
      Template = o.Template.Id 
     }); 
    } 

La tabla influencias entonces el siguiente aspecto:

CREATE TABLE [dbo].[Influences](
    [Id] [int] IDENTITY(1,1) NOT NULL, 
    [Template] [int] NULL, 
    [Trait] [int] NULL, 
    [Value] [int] NOT NULL, 
PRIMARY KEY CLUSTERED 
(
    [Id] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 

GO 

ALTER TABLE [dbo].[Influences] WITH CHECK ADD CONSTRAINT [Influence_Template] FOREIGN KEY([Template]) 
REFERENCES [dbo].[Templates] ([Id]) 
GO 

ALTER TABLE [dbo].[Influences] CHECK CONSTRAINT [Influence_Template] 
GO 

ALTER TABLE [dbo].[Influences] WITH CHECK ADD CONSTRAINT [Influence_Trait] FOREIGN KEY([Trait]) 
REFERENCES [dbo].[Traits] ([Id]) 
GO 

ALTER TABLE [dbo].[Influences] CHECK CONSTRAINT [Influence_Trait] 
GO 
+0

Entonces, ¿qué puedo hacer al respecto? El objeto Influence debe existir en C# como un objeto, pero no en la base de datos como una entidad. – Ciel

+1

@Shiraz - Creo que tienes eso al revés. Quiere Plantilla-> Rasgo en la base de datos, y Plantilla-> Influencia-> Rasgo en las entidades –

+0

Sí, estoy pensando que está malinterpretando mi pregunta. – Ciel

Cuestiones relacionadas