bin*_*bin 3 c# entity-framework-core .net-core
我有两个类,一个用于User
,一个用于Warn
上述用户可以接收的类,我想映射它们,但我在这样做时遇到了问题。
using System;
using System.Collections.Generic;
using System.Linq;
namespace web
{
public class User
{
public User()
{
}
public ICollection<MuteWarn> Mutes { get; set; }
public ICollection<Warn> Warns { get; set; }
public ICollection<Ban> Bans { get; set; }
public ICollection<Kick> Kicks { get; set; }
public int Id { get; set; }
public ulong DiscordId { get; set; }
public bool AntiBan { get; set; }
public ICollection<string> Permissions { get; set; }
public Level Level { get; set; }
public Mute CurrentMute { get; set; }
public string Name { get; set; }
public int Discrim { get; set; }
public string AvatarUrl { get; set; }
public Guild Guild { get; set; }
public bool HasPermission(string perm)
{
var res = Permissions.Where(x => x == perm);
if(res != null) return true;
return false;
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是User
课程,这是Warn
课程:
using System;
namespace web
{
public class Warn
{
public Warn()
{
Moderator = DataHelper.GetDefaultModerator();
}
public int Id { get; set; }
public string Reason { get; set; }
public DateTime Timestamp { get; set; }
public User Moderator { get; set; }
public User User { get; set; }
public Guild Guild { get; set; }
}
}
Run Code Online (Sandbox Code Playgroud)
如您所见,此类User
中有两个类型的对象,我想从 User 类访问它们,如下所示:
foreach(var w in User.Warns)
{
Console.WriteLine(w.Reason);
Console.WriteLine(w.Moderator.Name);
}
Run Code Online (Sandbox Code Playgroud)
等等。
版主和用户是两个不同的用户(即使他们可以是同一个人)。
版主是发出警告的人,用户是收到警告的用户。
每个用户可以有无限数量的警告。
出于某种原因,这不会建立,因为它找不到版主和用户之间的关系。
请帮忙,谢谢。
EF Core 具有根据域类结构确定元数据部分的约定。通常导航属性表示声明类型和目标类型之间存在关系。如果在声明类型的目标类型中有导航,则它们被视为定义关系的导航对。尽管在查找构成关系的导航对方面存在限制。如果存在歧义,则 EF Core 将不会创建关系。在您的案例中,User
类有一个Warns
具有目标类型的导航,Warn
但类Warn
有 2 个类型的导航User
- Moderator
&User
. 现在 EF 无法确定哪些导航是单一关系的一部分。所以这需要用户配置来定义关系从而正确构建模型。
假设User.Warns
&Warn.User
是 1 关系的一部分,因为警告包含用户收到的所有警告,因此Warn.User
应该指向User
. 并且Warn.Moderator
是没有反向导航的单独关系。有 2 种方法可以配置它。
数据注释
您可以InverseProperty
在导航上使用属性来告诉 EF Core 此导航的反向导航是什么。在您的情况下,这两种方法都可以解决问题。
[InverseProperty("User")]
public ICollection<Warn> Warns { get; set; }
Run Code Online (Sandbox Code Playgroud)
或者
[InverseProperty("Warns")]
public User User { get; set; }
Run Code Online (Sandbox Code Playgroud)
这将解决歧义并帮助 EF 找出对,以便约定将创建关系。
流利的API
您可以使用 fluent api 显式配置关系。您需要将此代码放在您的DbContext.OnModelCreating
方法中。
modelBuilder.Entity<User>().HasMany(e => e.Warns).WithOne(e => e.User);
Run Code Online (Sandbox Code Playgroud)
或者
modelBuilder.Entity<Warn>().HasOne(e => e.Moderator).WithMany();
Run Code Online (Sandbox Code Playgroud)
再次定义以上任何一项都可以消除歧义,并且模型构建正确。
有关如何配置关系的更多详细信息,您可以在文档中阅读