2010-09-22 19 views
6

Ho il seguente setup (che funziona bene). Utilizzo di CodeFirst (CTP4).Molte a molte relazioni senza tabelle a doppia giunzione, Entity Framework

Un modello ha un elenco di influenze, ogni influenza dà un valore a un tratto.

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; } 
} 

Il modello è configurato in questo modo.

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 
     }); 
    } 
} 

Questo funziona ma preferirei evitare il tavolo extra 'influenze'. Essenzialmente, "Influenze" è semplicemente un oggetto e non c'è bisogno di essere un negozio centrale per loro. In effetti, è più vantaggioso per il design che sto cercando di approcciare se non c'è un tavolo centrale per loro.

Desidero configurare uno scenario come questo per la tabella Modello ... Fondamentalmente le influenze non hanno una propria tabella, sono solo mappate da Tratto/Valore dove vengono utilizzate.

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"); 
    } 

Quando provo a farlo in questo modo, ottengo l'eccezione nel Mapping dei modelli.

System.InvalidOperationException stata gestita

La proposta espressione include un pattern non riconosciuta 'influence.Trait.Id'.


Di seguito si riporta l'intero codice del progetto, se necessario.

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

Chiunque? Per favore? Questo mi sta facendo impazzire. – Ciel

+1

Otterresti più risposte se pubblichi uno snippet di codice estremamente breve e semplice che cattura il problema nella sua forma minima invece dell'enorme quantità di codice che hai attualmente. Inoltre, quando dici "mi dà errori", devi includere il testo completo di errore/eccezione, altrimenti è l'equivalente di dire "non funziona". –

+2

Di solito, quando pubblico solo ciò che è necessario, mi viene da lamentare che non sto fornendo abbastanza codice per essere utile. Quindi questa volta ho appena pubblicato il progetto completo. L'ho modificato per essere più conciso e ho lasciato il codice completo in fondo per ogni riferimento necessario. – Ciel

risposta

1

OK, nuovo giorno nuova idea.

Ora ho installato CTP4 e ho ottenuto gli stessi 4 tavoli.

Il motivo per cui viene prodotta la relazione da molti a molti è che il modello non sa che un'influenza verrà utilizzata solo da un modello. Poi dovete dirgli che:

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; } 
} 

e:

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 tabella influenze sarà quindi simile a questa:

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

Quindi cosa posso fare al riguardo? L'oggetto Influence deve esistere in C# come oggetto, ma non nel database come entità. – Ciel

+1

@Shiraz - Penso che tu sia così indietro. Vuole Template-> Trait nel database e Template-> Influence-> Trait in entitites –

+0

Sì, penso che fraintenda la mia domanda. – Ciel

Problemi correlati