Propiedad de navegación sin declarar clave externa

Todos mis modelos contienen al menos dos asociaciones. Al modelar esto en ef4, solo he podido hacer esto sin una segunda propiedad de clave externa mediante el uso de la interfaz fluida. ForeignKey parece el atributo correcto para usar, excepto por el hecho de que requiere un parámetro de cadena.

Entonces mi pregunta es, ¿pueden tener una propiedad de navegación y declararla como tal usando un atributo?

public class User : IAuditable { // other code public virtual User Creator { get; set; } public virtual User Modifier { get; set; } } 

Creo que no es posible definir la relación solo con atributos de datos. El problema es que las convenciones de mapeo de EF asumen que el Creator y el Modifier son los dos extremos de una y la misma relación, pero no pueden determinar cuál es el principal y cuál es el dependiente de esta asociación. Por lo que puedo ver en la lista de atributos soportados, no hay opción para definir el principal y el extremo dependiente con anotaciones de datos.

Aparte de eso, supongo que realmente quieres dos relaciones , ambas con un final que no está expuesto en el modelo. Esto significa que su modelo es “no convencional” con respecto a las convenciones de mapeo. (Creo que una relación entre el Creator y el Modifier tiene sentido, desde un punto de vista semántico).

Entonces, en Fluent API, quieres esto:

 modelBuilder.Entity() .HasRequired(u => u.Creator) .WithMany(); modelBuilder.Entity() .HasRequired(u => u.Modifier) .WithMany(); 

Porque un User puede ser el creador o modificador de muchos otros registros de usuario. ¿Derecha?

Si desea crear estas dos relaciones sin Fluent API y solo con DataAnnotations, creo que debe introducir los Many-Ends de las asociaciones en su modelo, así:

 public class User { public int UserId { get; set; } [InverseProperty("Creator")] public virtual ICollection CreatedUsers { get; set; } [InverseProperty("Modifier")] public virtual ICollection ModifiedUsers { get; set; } [Required] public virtual User Creator { get; set; } [Required] public virtual User Modifier { get; set; } } 

Supongo que aquí se requieren Creator y Modifier , de lo contrario, podemos omitir el atributo [Required] .

Creo que es un caso claro en el que usar la API Fluent tiene mucho sentido y es mejor que modificar el modelo solo para evitar una configuración fluida.