回答

收藏

为什么左外方加入?

技术问答 技术问答 227 人阅读 | 0 人回复 | 2023-09-14

怪异的 (可能一点也不奇怪)& S- @3 ?3 Q: g) I/ O7 W
我有3个对象,即Employee,Rota和Department。( c* L6 [7 ]% ~
public class Employee' ?0 A- J# N" ]8 r  `" e8 D4 z' o( R
{, n3 U3 D# A( L4 |6 Y
    public int Id { get; set; }7 G2 P( y  b+ A5 R$ t, \; V/ m
    public String Name { get; set; }
+ G& t& m2 P, a    public virtual Department Department { get; set; }, x, X2 v/ Q. [. b# R, E
}
8 f3 R& O5 b6 A. B+ b. g, Ginternal class EmployeeMapping : EntityTypeConfiguration
. ]& W! `8 p$ t2 y6 b, B' f{
. q, F5 Z3 r: u! i    public EmployeeMapping()
' {. m# Q0 F5 f( q    {, F( @2 j5 ^/ ~4 b) N) @  D
        HasKey(a => a.Id);' H- M9 w* L/ Q1 K3 T# A; U" M
        Property(a => a.Id).HasColumnName("UserId");
6 ^6 X$ S1 |3 l6 X  i- h+ z        HasRequired(a => a.Department).WithOptional().Map(a => a.MapKey("DepartmentId"));
- r; F7 L! A2 v5 k3 L% p9 ]    }
/ \4 o: z. q/ Y. y}
1 G$ W- |/ w" cpublic class Department; y: f5 o: d0 f  R' X
{8 Z5 ~, E8 Q0 g2 t( {
    public int Id { get; set; }
3 G% H% u1 p6 o5 z4 Q    public String Name { get; set; }
- W: O% l2 P* a$ ?}9 v/ O/ r- q2 ^9 o( m  V( S
internal class DepartmentMapping : EntityTypeConfiguration! l2 a0 h$ z4 S& ~$ k& b. M& Z8 Y
{
& H% ^4 w* n% X. F    public DepartmentMapping()" A! R+ f9 [% G" S) m
    {
, A* L1 T, A& W% p9 d  w9 S! O5 d        HasKey(a => a.Id);
) K! D# R8 V! t% K/ G% V+ |        Property(a => a.Id).HasColumnName("DepartmentId");* x6 H9 J( g4 b% t4 V3 u/ m4 `" L
    }5 M/ f% A& W  M, R( W; A, b" w- @
}
4 S+ e+ E& \% }, ~, {public class Rota
5 |4 `1 F7 Y9 _5 s{
/ d1 n& U8 L* q0 d$ s$ t    public int Id { get; set; }
9 m& v# b6 w, T9 A; |4 m    public virtual Employee Employee { get; set; }
& O# c4 ]. P% @9 e! z5 h0 N    public virtual Department Department { get; set; }8 N- r- W$ G3 h
}
$ V. ]; d+ o: J. Ainternal class RotaMapping : EntityTypeConfiguration
5 n- i: c1 t/ [: l' k& W1 R" t{$ O9 M( Z. p. T* o. s+ [- G) r
    public RotaMapping()
3 L6 U7 U! m0 w( y$ N2 o    {
: {1 a. g, O+ N+ b, t: _8 I2 [% i        HasKey(a => a.Id);* l4 c9 Q. Q) U: D  S5 H
        Property(a => a.Id).HasColumnName("RotaId");3 g- j( P3 M, z1 b% f9 r
        HasOptional(a => a.Employee).WithOptionalDependent().Map(a => a.MapKey("EmployeeId"));  j2 c. u6 w# B- y* F- N
        HasOptional(a => a.Department).WithOptionalDependent().Map(a => a.MapKey("DepartmentId"));$ P. J: y7 G5 ]$ u* @4 J6 |
    }$ a  P4 d# @0 O, U; _& B
}
6 F) r; b) }; Q2 }  \5 t  O并不复杂,真的。Rota可以分配一个员工和/或部门,所有这些都使用Fluent进行配置。我所有的关联都是正确的(架构是完美的),但是我有一个奇怪的怪异之处。: h- G" X% s% Z
当我执行myContext.Departments.FirstOrDefault()并查看生成的SQL时,在Employee&Rota上有一个
) e" o2 p4 o/ p# F$ a% BLEFT OUTER JOIN 。为什么在那儿?5 ?7 [  ?- q$ @
我不希望它这样做。也许我的Fluent映射不正确?我已经尝试了各种方法,但似乎无法弄清楚。如果我想要一个Rota对象,我会理解,它将加入该部门。但不是相反!; P& B5 z' b7 o  I$ b) V
如果我这样做myContext.Departments.AsNoTracking().FirstOrDefault(),则不会执行 LEFT
0 l2 m' P2 Q! ~1 B. FOUTER JOIN的

( [( Q7 @- s: X7 J  Q. p有想法吗?
* m0 V' u; V# u% H               
9 G' C) N6 u! ]解决方案:2 m! m) o3 c+ \$ p. D% g" H
               
* y. l6 K0 A/ e6 s5 b, R8 T+ e# Q& j/ W3 C& f0 q' l$ N' D

0 d9 {2 c5 S* Q; @                原因是映射不正确。看起来正确,但事实并非如此。使用这些代替:
# I# m. ^; k) k: [internal class EmployeeMapping : EntityTypeConfiguration" l+ M1 x! g5 w: R) {5 O
{: Y" N  `. a( ~6 V$ g4 S
    public EmployeeMapping()9 U; d+ S$ f/ {
    {
$ O1 e$ A6 d' l9 [        HasKey(a => a.Id);
7 e, b( b3 _$ k# b' W( B7 o" p        Property(a => a.Id).HasColumnName("UserId");' s. b4 @2 z  t- R* l% _
        HasRequired(a => a.Department).WithMany()$ |7 `/ M' D5 C2 Y
                                                  .Map(a => a.MapKey("DepartmentId"));
3 z" N6 M& j% O, T$ W9 z* C1 f    }
& m1 c' }+ T) F# z' R# F}
/ K. d: ~+ k: T5 n; Tinternal class RotaMapping : EntityTypeConfiguration( t0 f5 r6 j( ~; F8 \7 N3 t0 J% \
{
( b/ A; z: j$ X2 Q    public RotaMapping()
0 v# D4 y* N4 ?6 g' N    {
9 o. i% ~! S0 P" [3 ~9 N2 U4 i        HasKey(a => a.Id);6 j5 @/ p- k3 Q8 k
        Property(a => a.Id).HasColumnName("RotaId");
, U0 Q7 y  }" J9 U3 C$ |3 J        HasOptional(a => a.Employee).WithMany(), x' O6 c, R1 K
                                              .Map(a => a.MapKey("EmployeeId"));
( t: L- h( A# H- t7 P' \        HasOptional(a => a.Department).WithMany()  j/ X- V& R6 j1 q
                                                  .Map(a => a.MapKey("DepartmentId"));0 F: v5 e7 V. q  g8 ?
    }
" m8 z6 a$ T$ Z: W9 x}* c4 J. E/ F9 b8 h; R% ?
创建数据库时,您的映射会正确解释,并且数据库看起来正确,但是EF认为您将所有关系一对一映射。这会使EF混淆,它将生成用于一对一创建内部实体引用的查询。当您告诉EF依赖实体是可选的时,这些一对左连接对于一对一关系是必需的-! y& V6 `/ i7 N! Q3 T/ ^/ P2 O5 b
EF除非加载它们的键,否则不知道它们是否存在。
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则