c# - many - entity framework one to one
Implementando la relación Zero Or One to Zero Or One en el código EF primero por la API Fluent (5)
public class OfficeAssignment { [Key] [ForeignKey("Instructor")] public int InstructorID { get; set; } [StringLength(50)] [Display(Name = "Office Location")] public string Location { get; set; } public virtual Instructor Instructor { get; set; } }
El atributo clave
Existe una relación de uno a cero o uno entre el instructor y las entidades OfficeAssignment. Una asignación de oficina solo existe en relación con el instructor al que está asignada y, por lo tanto, su clave principal también es su clave externa para la entidad del Instructor. Pero Entity Framework no puede reconocer automáticamente InstructorID como la clave principal de esta entidad porque su nombre no sigue la convención de nomenclatura ID o classnameID. Por lo tanto, el atributo clave se usa para identificarlo como la clave:
Tengo dos clases de POCO
public class Order
{
int id;
string code;
int? quotationId; //it is foreign key
public int Id{get;set;}
public string Code{get;set;}
public int? QuotationId{get;set;}
Quotation quotation;
public virtual Quotation Quotation { get; set; }
....
}
public class Quotation
{
int Id;
string Code;
public int Id{get;set;}
public string Code{get;set;}
Order order;
public virtual Order Order { get; set; }
....
}
cada pedido puede realizarse a partir de una oferta o de cero, y cada cita puede causar un pedido, por lo que tengo una relación "uno o cero" a "uno o cero", ¿cómo puedo implementar esto, primero en código EF mediante API fluida?
Adaptado de esta answer , prueba esto.
Primero, arregla tus clases:
public class Order
{
public int Id {get; set;}
public virtual Quotation Quotation { get; set; }
// other properties
}
public class Quotation
{
public int Id {get; set;}
public virtual Order Order { get; set; }
// other properties
}
A continuación, utilice la API con fluidez de esa manera:
modelBuilder.Entity<Quotation>()
.HasOptional(quote => quote.Order)
.WithRequired(order=> order.Quotation);
Básicamente, para relaciones 1: 1 o [0/1]: [0/1], EF necesita las claves principales para compartir.
Cambiando pocos a:
public class Order
{
public int OrderId { get; set; }
public virtual Quotation Quotation { get; set; }
}
public class Quotation
{
public int QuotationId { get; set; }
public virtual Order Order { get; set; }
}
y usando estos archivos de mapeo:
public class OrderMap : EntityTypeConfiguration<Order>
{
public OrderMap()
{
this.HasOptional(x => x.Quotation)
.WithOptionalPrincipal()
.Map(x => x.MapKey("OrderId"));
}
}
public class QuotationMap : EntityTypeConfiguration<Quotation>
{
public QuotationMap()
{
this.HasOptional(x => x.Order)
.WithOptionalPrincipal()
.Map(x => x.MapKey("QuotationId"));
}
}
tendremos esta base de datos (eso significa 0..1-0..1):
con un agradecimiento especial a ( Sr. Vahid Nasiri )
Consulte http://msdn.microsoft.com/en-us/data/jj591620 Relaciones de EF.
Un excelente libro http://my.safaribooksonline.com/book/-/9781449317867
Aquí hay una publicación del desarrollador de diciembre de 2010. Pero sigue siendo relevante http://social.msdn.microsoft.com/Forums/uk/adonetefx/thread/aed3b3f5-c150-4131-a686-1bf547a68804 El artículo anterior es un buen resumen o las posibles combinaciones aquí.
Una solución donde la Tabla dependiente tiene clave de la tabla primaria es posible.
Si quiere claves independientes donde ambos son directores en un escenario de PK / FK, no creo que pueda hacerlo primero en el código con la API de Fluent. Si comparten una clave, estás bien. 1: 1 opcional supone que el dependiente usa la clave de Primario.
Pero ya que necesita guardar una de las tablas antes que la otra. Puede verificar una de las claves externas con el código. O agregue el segundo Extranjero a la Base de Datos después de que el Código lo haya creado primero.
Te acercarás. Pero EF se quejará de claves foráneas conflictivas si quiere que ambas sean claves foráneas. Básicamente, la A depende de B; a A EF no le gusta, incluso si las columnas son nulables y técnicamente posibles en la BD.
Aquí usa este programa de prueba para probarlo. Solo comenten las cosas de Fluent API para probar algunas opciones. No pude conseguir EF5.0 para trabajar con PK / FK INDEPENDIENTE 0: 1 a 0: 1 Pero, por supuesto, hay compromisos razonables como se discutió.
using System.Data.Entity;
using System.Linq;
namespace EF_DEMO
{
class Program
{
static void Main(string[] args) {
var ctx = new DemoContext();
var ord = ctx.Orders.FirstOrDefault();
//. DB should be there now...
}
}
public class Order
{
public int Id {get;set;}
public string Code {get;set;}
public int? QuotationId { get; set; } //optional since it is nullable
public virtual Quotation Quotation { get; set; }
//....
}
public class Quotation
{
public int Id {get;set;}
public string Code{get;set;}
// public int? OrderId { get; set; } //optional since it is nullable
public virtual Order Order { get; set; }
//...
}
public class DemoContext : DbContext
{
static DemoContext()
{
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<DemoContext>());
}
public DemoContext()
: base("Name=Demo") { }
public DbSet<Order> Orders { get; set; }
public DbSet<Quotation> Quotations { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Order>().HasKey(t => t.Id)
.HasOptional(t => t.Quotation)
.WithOptionalPrincipal(d => d.Order)
.Map(t => t.MapKey("OrderId")); // declaring here via MAP means NOT declared in POCO
modelBuilder.Entity<Quotation>().HasKey(t => t.Id)
.HasOptional(q => q.Order)
// .WithOptionalPrincipal(p => p.Quotation) //as both Principals
// .WithOptionalDependent(p => p.Quotation) // as the dependent
// .Map(t => t.MapKey("QuotationId")); done in POCO.
;
}
}
}
Los procedimientos de Masouds son:
modelBuilder.Entity<Order>()
.HasOptional(o => o.Quotation)
.WithOptionalPrincipal()
.Map(o => o.MapKey("OrderId"));
modelBuilder.Entity<Quotation>()
.HasOptional(o => o.Order)
.WithOptionalPrincipal()
.Map(o => o.MapKey("QuotationId"));
Da:
Al cambiar el código a:
modelBuilder.Entity<Order>()
.HasOptional(o => o.Quotation)
.WithOptionalPrincipal(o=> o.Order);
Da: