偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)(DDD)中導(dǎo)航屬性的最佳實(shí)踐與性能優(yōu)化指南

開發(fā) 前端
在 C# 和 Entity Framework Core(EF Core)中,導(dǎo)航屬性允許您在實(shí)體之間遍歷關(guān)系。然而,使用不當(dāng)可能導(dǎo)致性能問題、緊耦合甚至循環(huán)引用。

在領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)(DDD)中,領(lǐng)域?qū)邮菓?yīng)用程序的核心,它包含了業(yè)務(wù)邏輯以及對(duì)現(xiàn)實(shí)世界概念進(jìn)行建模的實(shí)體。領(lǐng)域建模的一個(gè)關(guān)鍵方面是使用導(dǎo)航屬性定義實(shí)體之間的關(guān)系。

在 C# 和 Entity Framework Core(EF Core)中,導(dǎo)航屬性允許您在實(shí)體之間遍歷關(guān)系。然而,使用不當(dāng)可能導(dǎo)致性能問題、緊耦合甚至循環(huán)引用。

本文探討了在領(lǐng)域?qū)又袑?shí)現(xiàn)導(dǎo)航屬性的最佳實(shí)踐,同時(shí)保持設(shè)計(jì)的清晰和可維護(hù)性。

理解導(dǎo)航屬性

EF Core 中的導(dǎo)航屬性定義了實(shí)體之間的關(guān)系,例如:

? 一對(duì)一(例如,用戶 ? 用戶檔案)

? 一對(duì)多(例如,訂單 ? 訂單項(xiàng))

? 多對(duì)多(例如,學(xué)生 ? 課程)

示例:

public classOrder
{
    publicint Id { get; set; }
    publicstring OrderNumber { get; set; }
    public ICollection<OrderItem> Items { get; set; } // 一對(duì)多
}
publicclassOrderItem
{
    publicint Id { get; set; }
    publicstring ProductName { get; set; }
    publicint OrderId { get; set; } // 外鍵
    public Order Order { get; set; } // 導(dǎo)航回 Order
}

導(dǎo)航屬性的最佳實(shí)踐

謹(jǐn)慎使用延遲加載

EF Core 支持延遲加載,但如果使用不當(dāng),可能導(dǎo)致 N+1 查詢問題。

? 應(yīng)該做:

使用 virtual 關(guān)鍵字實(shí)現(xiàn)延遲加載(如果需要):

public virtual ICollection<OrderItem> Items { get; set; }

? 應(yīng)避免:

在 Web 應(yīng)用程序中過度使用延遲加載(更推薦使用 .Include() 進(jìn)行預(yù)先加載)。

使用顯式加載以獲得更好的控制

考慮使用顯式加載代替延遲加載:

var order = dbContext.Orders.First();
dbContext.Entry(order).Collection(o => o.Items).Load();

在不需要時(shí)避免雙向?qū)Ш?/span>

并非所有關(guān)系都需要雙向?qū)Ш健H绻?nbsp;OrderItem 不需要引用 Order,則可以省略:

public class OrderItem
{
    public int Id { get; set; }
    public string ProductName { get; set; }
    public int OrderId { get; set; } // 僅保留外鍵
    // public Order Order { get; set; } 不需要導(dǎo)航回 Order
}

使用私有 Set 器實(shí)現(xiàn)不可變性

為了強(qiáng)制執(zhí)行領(lǐng)域規(guī)則,限制屬性修改:

public IReadOnlyCollection<OrderItem> Items { get; private set; } = new List<OrderItem>();

小心處理聚合根

在 DDD 中,聚合根控制對(duì)子實(shí)體的訪問。避免暴露破壞封裝的導(dǎo)航屬性。

public class Order : AggregateRoot
{
    private readonly List<OrderItem> _items = new();
    public IReadOnlyCollection<OrderItem> Items => _items.AsReadOnly();

    public void AddItem(OrderItem item)
    {
        // 在添加前驗(yàn)證業(yè)務(wù)規(guī)則
        _items.Add(item);
    }
}

性能考量

注意 N+1 查詢問題

延遲加載可能觸發(fā)多個(gè)數(shù)據(jù)庫(kù)查詢。請(qǐng)使用:

? 預(yù)先加載(.Include()

? 投影(.Select())僅加載所需的數(shù)據(jù)。

考慮使用 DTO 代替直接暴露實(shí)體

直接返回領(lǐng)域?qū)嶓w可能導(dǎo)致數(shù)據(jù)過度獲取。為 API 使用 DTO(數(shù)據(jù)傳輸對(duì)象):

public class OrderDto
{
    public int Id { get; set; }
    public List<OrderItemDto> Items { get; set; }
}

避免循環(huán)引用

如果 Order 引用 User 并且 User 引用 Order,JSON 序列化可能會(huì)失敗。

? 解決方案:

? 在一個(gè)導(dǎo)航屬性上使用 [JsonIgnore]

? 配置 EF Core 忽略一側(cè)的關(guān)系:

modelBuilder.Entity<Order>()
    .HasOne(o => o.User)
    .WithMany()
    .OnDelete(DeleteBehavior.Restrict);

測(cè)試導(dǎo)航屬性

確保導(dǎo)航屬性在單元測(cè)試中按預(yù)期工作:

[Fact]
public void Order_Should_Have_Items()
{
    var order = new Order();
    order.AddItem(new OrderItem("Product1"));
    Assert.Single(order.Items);
}

即使沒有 EF Core,為何還要使用導(dǎo)航屬性?
導(dǎo)航屬性不僅僅是 ORM(EF Core)的一個(gè)功能——它們是一種領(lǐng)域建模工具。

使用導(dǎo)航屬性的關(guān)鍵理由:
表現(xiàn)力:清晰定義領(lǐng)域?qū)嶓w之間的關(guān)系。
封裝性:控制實(shí)體如何交互(例如,使用 Order.AddItem() 而不是直接操作列表)。
業(yè)務(wù)邏輯強(qiáng)制執(zhí)行:確保不變性(例如,一個(gè) OrderItem 不能沒有 Order 而存在)。
可測(cè)試性:更容易在沒有數(shù)據(jù)庫(kù)的情況下模擬和測(cè)試領(lǐng)域行為。

何時(shí)應(yīng)避免使用導(dǎo)航屬性(在沒有 EF Core 的情況下)?
? 如果性能至關(guān)重要(例如,在高負(fù)載系統(tǒng)中,對(duì)象遍歷成本高昂)。
? 如果使用微服務(wù)架構(gòu)(更傾向于通過 ID 進(jìn)行松耦合引用)。
? 如果使用 NoSQL 數(shù)據(jù)庫(kù)(其關(guān)系處理方式不同)。

責(zé)任編輯:武曉燕 來源: 架構(gòu)師老盧
相關(guān)推薦

2021-10-09 11:54:46

DDD微服務(wù)業(yè)務(wù)

2021-09-08 09:22:23

領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)

2024-11-27 15:33:17

軟件架構(gòu)DDD

2010-07-06 09:07:09

2017-07-14 10:55:05

2025-04-11 03:00:55

2023-08-29 07:53:17

領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)

2022-04-25 10:44:08

微服務(wù)架構(gòu)設(shè)計(jì)

2020-09-02 08:12:05

CodeDDD代碼

2011-08-11 09:45:25

2024-12-31 11:05:07

2016-11-17 09:00:46

HBase優(yōu)化策略

2017-03-01 20:53:56

HBase實(shí)踐

2014-03-19 14:34:06

JQuery高性能

2023-01-09 09:00:00

樹服務(wù)架構(gòu)驅(qū)動(dòng)決策

2014-09-26 10:00:25

驅(qū)動(dòng)設(shè)計(jì)DDD領(lǐng)域

2024-11-08 08:37:25

2025-03-27 03:20:00

C#開發(fā)字符串

2023-02-15 13:50:58

DDD戰(zhàn)略設(shè)計(jì)

2021-06-07 09:33:21

企業(yè)架構(gòu)驅(qū)動(dòng)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)