Подтвердить что ты не робот

Внедрение нулевого или одного нуля или одного отношения в коде 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?

4b9b3361

Ответ 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