簡體   English   中英

EF Core 3.1 Fluent API

[英]EF Core 3.1 Fluent API

我有兩個實體:

審計 class

public class Audit
{
  public string AuditId{get;set;}
  public int EmployeeId{get;set;}
  public virtual ModEmployee{get;set;}
}

員工 class

public class Employee
{
  public int EmployeeId{get;set}
}

在加載Set<Audit>時,我希望填充 Audit class 的 Employee 屬性。 這顯然是一對多關系的情況,其中一個審計將有一個員工,但一個員工可以在多個審計中。

我的 Fluent API 如下所示:

protected override OnModelCreating(ModelBuilder modelBuilder)
{
  modelBuilder.Entity<Audit>()
 .HasOne(a=>a.ModEmployee)
 .WithMany()
 .HasForeignKey("EmployeeId");//a=>a.EmployeeId wont work.

}

我一直在尋找解決方案一段時間,並從這個答案中獲取了一些輸入,但它是一對一的。 然后這個資源顯示了一種方法,但這需要我在員工 class 中收集審計。


我無法更改現有模型或添加注釋,因為它們已被其他實體框架版本(非核心)使用。


目前我收到以下錯誤:

System.InvalidOperationException:'無法確定'Employee'類型的導航屬性'Employee.ModEmployee'表示的關系。 手動配置關系,或使用“[NotMapped]”屬性或使用“OnModelCreating”中的“EntityTypeBuilder.Ignore”忽略此屬性。

如果我在 Audit 的構建器上添加忽略方法,錯誤就會消失,如下所示: .Ignore(a=>a.ModEmployee)但我不會在 Audit 中獲得實體 object。 任何幫助將不勝感激。 我在 EFCore 3.1.10 上。 謝謝閱讀。 任何幫助將不勝感激。


嘗試在Audit class 中將類型從int更改為Employee 應該可以正常工作,因為這是在流暢的 API 中關聯外鍵的正確方法。

PS:FK 屬性字符串應與Employee中的完全相同,這已經發生了。

我最近有同樣的問題。 這對我有用:

方法 1:參考 Audit 集合定義您的 Employee class:

public class Employee
{
  public int EmployeeId { get; set }
  public virtual ICollection<Audit> Audits { get; set; }
}

然后在您的 model 構建器中以這種方式定義關系:

builder.Entity<Audit>().HasOne(e => e.ModEmployee).WithMany(ae => ae.Audits).HasForeignKey(k => k.EmployeeId);

您總是需要在每個 class 中定義集合。

編輯!!

方法二:

public class Audit
{
  public string AuditId{get;set;}
  public Employee Employee { get; set; }
}

我知道這需要你編輯你的 class 但相信我這會讓事情變得更容易。

如果您無法修改 model 類。

您可以簡單地在您的上下文中添加一個檢索審計的方法。

using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace EFCoreFluentApi1.Context
{
    public class MyContext : DbContext
    {
        public DbSet<Audit> Audit { get; set; }
        public DbSet<Employee> Employee { get; set; }

        public MyContext(DbContextOptions options) : base(options)
        {
        }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            base.OnConfiguring(optionsBuilder);

        }
        protected override void OnModelCreating(ModelBuilder builder)
        {
            base.OnModelCreating(builder);

            builder.Entity<Employee>().HasKey(e => e.EmployeeId);
            builder.Entity<Employee>().Property(e => e.EmployeeId);

            builder.Entity<Audit>().HasKey(e => e.AuditId);
            builder.Entity<Audit>().Property(e => e.AuditId);
            builder.Entity<Audit>().HasOne(e => e.ModEmployee).WithMany().HasForeignKey(e => e.EmployeeId);

            builder.Entity<Employee>().HasData(new Employee[]
            {
                new Employee{ EmployeeId = 1 },
                new Employee{ EmployeeId = 2 },
                new Employee{ EmployeeId = 3 },
                new Employee{ EmployeeId = 4 }
            });

            builder.Entity<Audit>().HasData(
                new Audit[]
                {
                    new Audit
                    {
                        AuditId = "Audit1",
                        EmployeeId = 1
                    },
                    new Audit
                    {
                        AuditId = "Audit2",
                        EmployeeId = 1
                    },
                    new Audit
                    {
                        AuditId = "Audit3",
                        EmployeeId = 1
                    },
                    new Audit
                    {
                        AuditId = "Audit4",
                        EmployeeId = 2
                    },
                    new Audit
                    {
                        AuditId = "Audit5",
                        EmployeeId = 3
                    },
                    new Audit
                    {
                        AuditId = "Audit6",
                        EmployeeId = 3
                    },
                    new Audit
                    {
                        AuditId = "Audit7",
                        EmployeeId = 4
                    },
                    new Audit
                    {
                        AuditId = "Audit8",
                        EmployeeId = 4
                    },
                    new Audit
                    {
                        AuditId = "Audit9",
                        EmployeeId = 4
                    },
                    new Audit
                    {
                        AuditId = "Audit10",
                        EmployeeId = 4
                    }

                });
        }

        public ICollection<Audit> GetAudits(int employeeId)
        {
            return Audit.Where(e => e.EmployeeId == employeeId).ToList();
        }

    }
}

如果需要填充 ModEmployee,可以使用 Include 方法。

using EFCoreFluentApi1.Context;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using System;
using System.IO;
using System.Linq;
using System.Text.Json;

namespace EFCoreFluentApi1
{
    class Program
    {
        static void Main(string[] args)
        {
            IConfiguration configuration = new ConfigurationBuilder().
                    SetBasePath(Directory.GetCurrentDirectory())
                    .AddJsonFile("appsettings.json", false, true)
                    .Build();


            DbContextOptions options = new DbContextOptionsBuilder<MyContext>()
                .UseSqlServer(configuration.GetConnectionString("MyConnectionString"))
                .EnableSensitiveDataLogging(true).Options;

            using (var context = new MyContext(options))
            {
                var result = context.Audit.Include(e => e.ModEmployee).ToList(); //ModEmployee is populated 
                //var result = context.Audit.ToList(); //ModEmployee = null
                foreach (var value in result)
                {
                    Console.WriteLine($"█ Audit: {value.AuditId}");
                    Console.WriteLine(JsonSerializer.Serialize(value));
                    Console.WriteLine();
                }
                Console.ReadLine();
            }
        }
    }
}

檢查我在https://github.com/JomaStackOverflowAnswers/EFCoreFluentApi1中的示例這個項目是<TargetFramework>netcoreapp3.1</TargetFramework>

檢查 IsRequired 顯式https://docs.microsoft.com/en-us/ef/core/modeling/entity-properties?tabs=fluent-api%2Cwithout-nrt#explicit-configuration

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM