首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >EF Core 3.1 Fluent API

EF Core 3.1 Fluent API
EN

Stack Overflow用户
提问于 2021-01-18 16:37:18
回答 3查看 194关注 0票数 3

我有两个实体:

审计类

代码语言:javascript
复制
public class Audit
{
  public string AuditId{get;set;}
  public int EmployeeId{get;set;}
  public virtual ModEmployee{get;set;}
}

雇员类

代码语言:javascript
复制
public class Employee
{
  public int EmployeeId{get;set}
}

在加载Set<Audit>时,我希望填充审核类的Employee属性。这显然是一对多的关系,其中一个审计将有一个雇员,但一个雇员可以在几个审计。

我的Fluent API如下所示:

代码语言:javascript
复制
protected override OnModelCreating(ModelBuilder modelBuilder)
{
  modelBuilder.Entity<Audit>()
 .HasOne(a=>a.ModEmployee)
 .WithMany()
 .HasForeignKey("EmployeeId");//a=>a.EmployeeId wont work.

}

我寻找一个解决方案已经有一段时间了,从这个答案获得了一些输入,但是它是一对一的。然后,这一资源展示了一种方法,但这将要求我在Employee类中拥有一个审计集合。

I不能更改现有模型或添加注释,因为其他实体框架版本(非核心版本)已经在使用它们。

目前,我正在收到以下错误:

System.InvalidOperationException:“无法确定”Employee“类型的导航属性”Employee.ModEmployee“表示的关系。或者手动配置关系,或者使用“NotMapped”属性忽略此属性,或者在“OnModelCreating”中使用“EntityTypeBuilder.Ignore”。

如果我在审计构建器上添加了一个忽略方法,那么错误就会消失,比如:.Ignore(a=>a.ModEmployee),但是我不会在审计中获得实体对象。任何帮助都将不胜感激。我在EFCore 3.1.10上。谢谢你的阅读。任何帮助都将不胜感激。

EN

回答 3

Stack Overflow用户

发布于 2021-01-18 17:19:22

尝试将您的类型从int更改为Audit类中的Employee。应该工作得很好,因为这是在fluent API中关联外键的正确方法。

PS: FK属性字符串应该与Employee内部完全相同,已经发生了什么。

票数 0
EN

Stack Overflow用户

发布于 2021-01-18 17:46:11

我最近也有同样的问题。这对我起了作用:

方法1:使用对审核集合的引用定义Employee类:

代码语言:javascript
复制
public class Employee
{
  public int EmployeeId { get; set }
  public virtual ICollection<Audit> Audits { get; set; }
}

然后,在您的模型构建器中,这样定义关系:

代码语言:javascript
复制
builder.Entity<Audit>().HasOne(e => e.ModEmployee).WithMany(ae => ae.Audits).HasForeignKey(k => k.EmployeeId);

您总是需要在每个类中定义集合。

编辑!!

方法2:

代码语言:javascript
复制
public class Audit
{
  public string AuditId{get;set;}
  public Employee Employee { get; set; }
}

我知道这将需要你编辑你的课程,但相信我,这将使事情变得容易得多。

票数 0
EN

Stack Overflow用户

发布于 2021-01-18 20:00:28

如果无法修改模型类,请执行以下操作。

您可以简单地在上下文中添加检索审核的方法。

代码语言:javascript
复制
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方法。

代码语言:javascript
复制
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://learn.microsoft.com/en-us/ef/core/modeling/entity-properties?tabs=fluent-api%2Cwithout-nrt#explicit-configuration

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65778575

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档