Внедрение нулевого или одного нуля или одного отношения в коде EF сначала с помощью API Fluent
У меня есть два класса 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; }
....
}
каждый Заказ может быть сделан из одной или нулевой цитаты, и каждая цитата может вызывать заказ, поэтому у меня есть отношение "один или ноль" к "одному или нулю", как я могу реализовать это в коде EF сначала с помощью свободного API?
Ответы
Ответ 1
Изменив pocos на:
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; }
}
и используя эти файлы сопоставления:
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"));
}
}
мы будем иметь эту БД (это означает 0..1-0..1):
![enter image description here]()
с особой благодарностью (г-н Вахид Насири)
Ответ 2
Процедура @Masoud была:
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"));
Это дает:
![enter image description here]()
Изменив код на:
modelBuilder.Entity<Order>()
.HasOptional(o => o.Quotation)
.WithOptionalPrincipal(o=> o.Order);
Это дает:
![enter image description here]()
Ответ 3
См. Http://msdn.microsoft.com/en-us/data/jj591620 EF Relationships
Отличная книга http://my.safaribooksonline.com/book / -/9781449317867
Вот сообщение от разработчика от декабря 2010 года. Но все еще актуально http://social.msdn.microsoft.com/Forums/uk/adonetefx/thread/aed3b3f5-c150-4131-a686-1bf547a68804 Приведенная выше статья является хорошим резюме или возможные комбинации здесь.
Возможно решение, в котором зависимая таблица имеет ключ от первичной таблицы.
Если вам нужны независимые ключи, где оба являются принципалами в сценарии PK/FK, я не думаю, что вы можете сделать это сначала в коде с помощью Fluent API. Если они разделяют ключ, вы в порядке. Опционально 1:1 предполагает, что зависимый использует ключ от Primary.
Но так как вам нужно сохранить одну из таблиц раньше другой. Вы можете проверить один из иностранных ключей с помощью кода. ИЛИ добавьте второй объект Foreign в базу данных после того, как код впервые его создал.
Вы приблизитесь. Но EF будет жаловаться на конфликтующие внешние ключи, если вы хотите, чтобы оба были внешними ключами. По существу, A зависит от B, зависит от A, который EF не любит, даже если столбцы обнуляются и технически возможны на БД.
Здесь используйте эту тестовую программу, чтобы попробовать это. Просто прокомментируйте материал Fluent API, чтобы попробовать некоторые варианты. Я не мог заставить EF5.0 работать с НЕЗАВИСИМЫМИ PK/FK от 0: 1 до 0: 1. Но, конечно, есть разумные компромиссы, как обсуждалось.
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.
;
}
}
}
Ответ 4
Адаптированный из этого , попробуйте это.
Сначала исправьте свои классы:
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
}
Затем используйте свободный API:
modelBuilder.Entity<Quotation>()
.HasOptional(quote => quote.Order)
.WithRequired(order=> order.Quotation);
В принципе, для отношений 1:1 или [0/1]: [0/1] EF нужны первичные ключи для совместного использования.
Ответ 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; }
}
Атрибут ключа
Существует отношение "один к нулю" между инструктором и сущностями OfficeAssignment. Назначение офиса существует только в отношении инструктора, которому он назначен, и поэтому его первичный ключ также является его внешним ключом для объекта инструктора. Но Entity Framework не может автоматически распознавать InstructorID в качестве первичного ключа этого объекта, потому что его имя не соответствует соглашению об именах идентификаторов или имен имен. Поэтому атрибут Key используется для идентификации его как ключа:
https://www.asp.net/mvc/overview/getting-started/getting-started-with-ef-using-mvc/creating-a-more-complex-data-model-for-an-asp-net-mvc-application