แชร์ผ่าน


เริ่มต้นใช้งานด่วน: เชื่อมต่อแอปพลิเคชัน .NET Aspire ของคุณกับฐานข้อมูล SQL

นําไปใช้กับ:ฐานข้อมูล SQL ใน Microsoft Fabric

ในบทช่วยสอนนี้ เรียนรู้วิธีเชื่อมต่อโปรแกรมประยุกต์ .NET Aspire ของคุณกับฐานข้อมูล SQL ใน Microsoft Fabric (ตัวอย่าง)

ฐานข้อมูล SQL ใน Fabric ช่วยให้คุณเชื่อมต่อแอปพลิเคชันของคุณได้อย่างรวดเร็ว ในบทความนี้ คุณจะเชื่อมต่อแอปพลิเคชัน .NET Aspire กับฐานข้อมูล SQL ใน Fabric โดยใช้ส AdventureWorksLT คีมาตัวอย่าง คําแนะนํานี้ใช้ Visual Studio Code ซึ่งเมื่อรวมกับ ความจุทดลองใช้ Fabric จะช่วยให้คุณทําคําแนะนําทั้งหมดนี้ได้ฟรี

ข้อกําหนดเบื้องต้น

เพิ่มหน้าใหม่เพื่อแสดงรายละเอียดผลิตภัณฑ์ AdventureWorks

เริ่มต้นใช้งานด่วน: สร้างโซลูชัน .NET Aspire แรกของคุณ สร้างโซลูชัน .NET Aspire ใหม่ด้วย API และส่วนหน้าของเว็บ โซลูชันประกอบด้วยโครงการต่อไปนี้:

  • AspireSample.ApiService: โปรเจ็กต์ API บนเว็บที่แสดงการพยากรณ์อากาศ
  • AspireSample.AppHost: โปรเจ็กต์ผู้ประสานงานที่เชื่อมต่อและกําหนดค่าโปรเจ็กต์และบริการต่างๆ ของแอปของคุณ ตั้งค่าตัวประสานงานเป็นโปรเจ็กต์เริ่มต้น
  • AspireSample.ServiceDefaults: ไลบรารีคลาสที่ใช้ร่วมกันซึ่งเก็บการกําหนดค่าที่นํากลับมาใช้ใหม่ได้ทั่วทั้งโครงการในโซลูชันของคุณ
  • AspireSample.Web: แอป Blazor ที่มีส่วนติดต่อผู้ใช้บนเว็บสําหรับโซลูชัน

สร้างโมเดลฐานข้อมูลและคลาสบริบท

ขั้นแรก ให้ติดตั้ง EF Core ใน AspireSample.ApiService โครงการ

  1. ใน หน้าต่างเทอร์มินัล ใน Visual Studio Code ไปที่ AspireSample.ApiService ไดเรกทอรีโครงการ แล้วเรียกใช้:

    dotnet add package Aspire.Microsoft.EntityFrameworkCore.SqlServer
    
  2. เมื่อต้องการแสดงผลิตภัณฑ์ ให้เพิ่มแฟ้มใหม่ที่มีชื่อด้วย Product.cs คลาสแบบจําลองต่อไปนี้ Product ที่รากของ AspireSample.ApiService โครงการ:

    using Microsoft.EntityFrameworkCore;
    using System.ComponentModel.DataAnnotations;
    using System.ComponentModel.DataAnnotations.Schema;
    
    namespace AspireSample.ApiService;
    
    [Table("Product", Schema = "SalesLT")]
    public sealed class Product
    {
      public int ProductID { get; set; }
      [Required]
      public string? Name { get; set; }
      public string ProductNumber { get; set; } = string.Empty;
      public string? Color { get; set; }
      [Precision(18, 2)]
      public decimal StandardCost { get; set; } = 0.0m;
      [Precision(18, 2)]
      public decimal ListPrice { get; set; } = 0.0m;
      public string? Size { get; set; }
      [Precision(8, 2)]
      public decimal? Weight { get; set; }
      public int? ProductCategoryID { get; set; }
      public int? ProductModelID { get; set; }
      public DateTime SellStartDate { get; set; } = DateTime.Now;
      public DateTime? SellEndDate { get; set; }
      public DateTime? DiscontinuedDate { get; set; }
      public byte[]? ThumbNailPhoto { get; set; }
      public string? ThumbnailPhotoFileName { get; set; }
      public Guid RowGuid { get; set; } = Guid.NewGuid();
      public DateTime ModifiedDate { get; set; } = DateTime.Now;
    }
    
  3. เพิ่มไฟล์ใหม่ที่มีชื่อด้วย AdventureWorksDbContext.cs คลาสบริบทข้อมูลต่อไปนี้ AdventureWorksDbContext ที่รากของ AspireSample.ApiService โครงการ คลาสนี้ใช้เพื่อ System.Data.Entity.DbContext ทํางานกับ EF Core และแสดงฐานข้อมูลของคุณ

    using System.ComponentModel.DataAnnotations.Schema;
    using Microsoft.EntityFrameworkCore;
    using Microsoft.Extensions.Options;
    
    namespace AspireSample.ApiService;
    
    public class AdventureWorksDbContext(DbContextOptions options) : DbContext(options)
    {
      public DbSet<Product> Products => Set<Product>();
    }
    
  4. บันทึกการเปลี่ยนแปลงของคุณโดยเลือก ไฟล์>บันทึกทั้งหมด

เพิ่มส่วนติดต่อผู้ใช้ Scalar ลงในโปรเจ็กต์ API

ใช้ Scalar UI เพื่อทดสอบ AspireSample.ApiService โปรเจ็กต์ มาติดตั้งและกําหนดค่ากัน:

  1. ใน หน้าต่างเทอร์มินัล ใน Visual Studio Code นําทางไปยัง AspireSample.ApiService ไดเรกทอรีโครงการ แล้วเรียกใช้:

    dotnet add package Scalar.AspNetCore
    
  2. ในAspireSample.ApiServiceโครงการ ให้เปิดไฟล์Program.cs

  3. เพิ่มบรรทัดโค้ดต่อไปนี้ที่ด้านบนของไฟล์:

    using Scalar.AspNetCore;
    
  4. ค้นหาบรรทัดของรหัสต่อไปนี้:

    if (app.Environment.IsDevelopment())
    {
      app.MapOpenApi();
    }
    
  5. แก้ไขรหัสนั้นให้ตรงกับบรรทัดต่อไปนี้:

    if (app.Environment.IsDevelopment())
    {
      app.MapOpenApi();
      app.MapScalarApiReference(_ => _.Servers = [ ]);
    }
    
  6. หากต้องการบันทึกการเปลี่ยนแปลง ให้เลือก ไฟล์บันทึก>ทั้งหมด

กําหนดค่าสตริงการเชื่อมต่อในโครงการโฮสต์แอป

โดยปกติ เมื่อคุณสร้างโซลูชันแบบ Cloud-Native ด้วย .NET Aspire คุณจะเรียกใช้ Aspire.Hosting.SqlServerBuilderExtensions.AddSqlServer วิธีการเพื่อเริ่มต้นคอนเทนเนอร์ที่เรียกใช้อินสแตนซ์ SQL Server คุณส่งผ่านทรัพยากรนั้นไปยังโครงการอื่นๆ ในโซลูชันของคุณที่ต้องการการเข้าถึงฐานข้อมูล

อย่างไรก็ตาม ในกรณีนี้ คุณต้องการทํางานกับฐานข้อมูล SQL ที่มีอยู่ใน Fabric มีความแตกต่างสามประการในโครงการโฮสต์แอป:

  • คุณไม่จําเป็นต้องติดตั้ง Aspire.Hosting.SqlServer การผสานรวมโฮสติ้ง
  • คุณเพิ่มสตริงการเชื่อมต่อในไฟล์การกําหนดค่า เช่น appsetting.json.
  • คุณโทรเพื่อสร้าง Aspire.Hosting.ParameterResourceBuilderExtensions.AddConnectionString ทรัพยากรที่คุณส่งต่อไปยังโครงการอื่น โครงการเหล่านั้นใช้ทรัพยากรนี้เพื่อเชื่อมต่อกับฐานข้อมูลที่มีอยู่

มาใช้การกําหนดค่านั้นกัน:

  1. ใน Visual Studio Code ใน AspireSample.AppHost โครงการ ให้เปิด appsetting.json ไฟล์

  2. แทนที่เนื้อหาทั้งหมดของไฟล์ด้วยรหัสต่อไปนี้:

    {
      "ConnectionStrings": {
          "sql": "sql_connection_string"
      },
      "Logging": {
          "LogLevel": {
              "Default": "Information",
              "Microsoft.AspNetCore": "Warning",
              "Aspire.Hosting.Dcp": "Warning"
          }
      }
    }
    
  3. ในเว็บเบราว์เซอร์ของคุณ ให้นําทางไปยังฐานข้อมูล SQL ของคุณที่โหลดด้วยข้อมูลตัวอย่าง AdventureWorks

  4. เลือกไอคอนการตั้งค่า จากนั้นเลือก สตริงการเชื่อมต่อ และคัดลอก สตริงการเชื่อมต่อ ADO.NET ทั้งหมด

  5. แทนที่ sql_connection_string ข้อความในแฟ้ม appsetting.json ด้วยสตริงการเชื่อมต่อ ADO.NET ที่คุณเพิ่งคัดลอก

  6. ในAspireSample.AppHostโครงการ ให้เปิดไฟล์AppHost.cs

  7. ค้นหาบรรทัดของรหัสต่อไปนี้:

    var builder = DistributedApplication.CreateBuilder(args);
    
  8. ทันทีหลังจากบรรทัดนั้น ให้เพิ่มบรรทัดของโค้ดนี้ ซึ่งรับสตริงการเชื่อมต่อจากไฟล์การกําหนดค่า:

    var connectionString = builder.AddConnectionString("sql");
    
  9. ค้นหาบรรทัดโค้ดต่อไปนี้ ซึ่งสร้างทรัพยากรสําหรับ AspireSample.ApiService โครงการ:

    var apiService = builder.AddProject<Projects.AspireSample_ApiService>("apiservice")
        .WithHttpHealthCheck("/health");
    
  10. ปรับเปลี่ยนบรรทัดนั้นให้ตรงกับรหัสต่อไปนี้ ซึ่งสร้างทรัพยากรและส่งสตริงการเชื่อมต่อไปยังรายการนั้น:

    var apiService = builder.AddProject<Projects.AspireSample_ApiService>("apiservice")
        .WithHttpHealthCheck("/health")
        .WithReference(connectionString);
    
  11. หากต้องการบันทึกการเปลี่ยนแปลง ให้เลือก ไฟล์บันทึก>ทั้งหมด

ใช้ฐานข้อมูลในโปรเจ็กต์ API

เมื่อกลับไปที่ AspireSample.ApiService โครงการ คุณต้องรับทรัพยากรสตริงการเชื่อมต่อจากโฮสต์แอป แล้วใช้ทรัพยากรเพื่อสร้างฐานข้อมูล:

  1. ในAspireSample.ApiServiceโครงการ ให้เปิดไฟล์Program.cs

  2. เพิ่มบรรทัดโค้ดต่อไปนี้ที่ด้านบนของไฟล์:

    using AspireSample.ApiService;
    
  3. ค้นหาบรรทัดของรหัสต่อไปนี้:

    var builder = WebApplication.CreateBuilder(args);
    
  4. ทันทีหลังจากบรรทัดนั้น ให้เพิ่มบรรทัดของรหัสนี้:

    builder.AddSqlServerDbContext<AdventureWorksDbContext>("sql");
    
  5. ค้นหาบรรทัดของรหัสต่อไปนี้:

    app.MapDefaultEndpoints();
    
  6. ทันทีหลังจากบรรทัดนั้น ให้เพิ่มบรรทัดโค้ดเหล่านี้:

    app.UseExceptionHandler("/Error", createScopeForErrors: true);
    app.UseHsts();
    
  7. หากต้องการบันทึกการเปลี่ยนแปลง ให้เลือก ไฟล์บันทึก>ทั้งหมด

เพิ่มโค้ดเพื่อสืบค้นผลิตภัณฑ์จากฐานข้อมูล

ในเทมเพลตโซลูชันเริ่มต้น .NET Aspire API จะสร้างการพยากรณ์อากาศแบบสุ่มห้ารายการและส่งคืนเมื่อโครงการอื่นร้องขอ มาเพิ่มโค้ดที่สืบค้นฐานข้อมูล:

  1. ในAspireSample.ApiServiceโครงการ ให้เปิดไฟล์Program.cs

  2. ที่ด้านบนของไฟล์ ให้เพิ่มบรรทัดโค้ดต่อไปนี้:

    using Microsoft.AspNetCore.Mvc;
    using Microsoft.EntityFrameworkCore;
    
  3. ค้นหารหัสต่อไปนี้:

    string[] summaries = ["Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"];
    
    app.MapGet("/weatherforecast", () =>
    {
        var forecast = Enumerable.Range(1, 5).Select(index =>
            new WeatherForecast
            (
                DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
                Random.Shared.Next(-20, 55),
                summaries[Random.Shared.Next(summaries.Length)]
            ))
            .ToArray();
        return forecast;
    })
    .WithName("GetWeatherForecast");
    
  4. ทันทีหลังจากรหัสนั้น ให้เพิ่มบรรทัดต่อไปนี้:

    app.MapGet("/productList", async ([FromServices] AdventureWorksDbContext context) =>
    {
        var product = await context.Products.OrderBy(p=>p.ProductID).ToArrayAsync();
        return product;
    })
    .WithName("GetProductList");
    
  5. หากต้องการบันทึกการเปลี่ยนแปลง ให้เลือก ไฟล์บันทึก>ทั้งหมด

เพิ่มรหัสเพื่อแสดงผลิตภัณฑ์จากฐานข้อมูล

ในเทมเพลตโซลูชันเริ่มต้น .NET Aspire โครงการเว็บมีหน้าตัวอย่างสองสามหน้า มาเพิ่มหน้าอื่นเพื่อแสดงรายละเอียดผลิตภัณฑ์จากฐานข้อมูล:

  1. ในAspireSample.Webโครงการ ให้เปิดไฟล์AspireSample.Web.csproj

  2. ค้นหารหัสต่อไปนี้:

    <ItemGroup>
       <ProjectReference Include="..\AspireSample.ServiceDefaults\AspireSample.ServiceDefaults.csproj" />
    </ItemGroup>
    
  3. เพิ่มการอ้างอิงโครงการสําหรับ AspireSample.ApiServerตัวอย่างเช่น:

    <ItemGroup>
       <ProjectReference Include="..\AspireSample.ServiceDefaults\AspireSample.ServiceDefaults.csproj" />
       <ProjectReference Include="..\AspireSample.ApiService\AspireSample.ApiService.csproj" /> 
     </ItemGroup>
    
  4. เมื่อต้องการดึงข้อมูลระเบียนผลิตภัณฑ์ ให้เพิ่มไฟล์ใหม่ที่มีชื่อ ProductApiClient.cs ด้วยคลาสต่อไปนี้ ProductApiClient ที่รากของ AspireSample.Web โครงการ:

    using AspireSample.ApiService;
    
    namespace AspireSample.Web;
    
    public class ProductApiClient(HttpClient httpClient)
    {
        public async Task<Product[]> GetProductAsync(int maxItems = 300, CancellationToken cancellationToken = default)
        {
            List<Product>? products = null;
    
            await foreach (var product in httpClient.GetFromJsonAsAsyncEnumerable<Product>("/productList", cancellationToken))
            {
                if (products?.Count >= maxItems)
                {
                    break;
                }
                if (product is not null)
                {
                    products ??= [];
                    products.Add(product);
                }
            }
    
            return products?.ToArray() ?? [];
        }
    }
    
  5. ในAspireSample.Webโครงการ ให้เปิดไฟล์Program.cs

  6. ค้นหารหัสต่อไปนี้:

     builder.Services.AddHttpClient<WeatherApiClient>(client =>
     {
         // This URL uses "https+http://" to indicate HTTPS is preferred over HTTP.
         // Learn more about service discovery scheme resolution at https://aka.ms/dotnet/sdschemes.
         client.BaseAddress = new("https+http://apiservice");
     });
    
  7. ทันทีหลังจากรหัสนั้น ให้เพิ่มบรรทัดต่อไปนี้:

     builder.Services.AddHttpClient<ProductApiClient>(client =>
     {
         // This URL uses "https+http://" to indicate HTTPS is preferred over HTTP.
         // Learn more about service discovery scheme resolution at https://aka.ms/dotnet/sdschemes.
         client.BaseAddress = new("https+http://apiservice");
     });
    
  8. ในAspireSample.Webโปรเจ็กต์ ให้ขยายโฟลเดอร์หน้าคอมโพเนนต์> สร้างไฟล์ใหม่ในโฟลเดอร์ Pages ที่ชื่อและ Products.razor วางรหัสต่อไปนี้ลงไป

    @using AspireSample.ApiService;
    @using Microsoft.AspNetCore.Components.Web
    @page "/products"
    @attribute [StreamRendering(true)]
    @attribute [OutputCache(Duration = 5)]
    
    @inject ProductApiClient ProductApi
    
    <PageTitle>Products</PageTitle>
    
    <h1>Products</h1>
    
    <p>This component demonstrates showing data loaded from a backend API service that reads data from a database.</p>
    
    @if (products == null)
    {
      <p><em>Loading...</em></p>
    }
    else
    {
      <table class="table">
          <thead>
              <tr>
                  <th>Thumbnail</th>
                  <th>ProductID</th>
                  <th>Name</th>
                  <th>ProductNumber</th>
                  <th>Color</th>
                  <th>StandardCost</th>
                  <th>ListPrice</th>
                  <th>Size</th>
                  <th>Weight</th>
                  <th>ProductCategoryID</th>
                  <th>ProductModelID</th>
                  <th>SellStartDate</th>
                  <th>SellEndDate</th>
                  <th>DiscontinuedDate</th>
                  <th>ThumbnailPhotoFileName</th>
                  <th>RowGuid</th>
                  <th>ModifiedDate</th>
              </tr>
          </thead>
          <tbody>
              @foreach (var product in products)
              {
                  <tr>
                      <td><img src="@GetImageString(product.ThumbNailPhoto)"/></td>
                      <td>@product.ProductID</td>
                      <td>@product.Name</td>
                      <td>@product.ProductNumber</td>
                      <td>@product.Color</td>
                      <td>@product.StandardCost</td>
                      <td>@product.ListPrice</td>
                      <td>@product.Size</td>
                      <td>@product.Weight</td>
                      <td>@product.ProductCategoryID</td>
                      <td>@product.ProductModelID</td>
                      <td>@product.SellStartDate.ToShortDateString()</td>
                      <td>@(product.SellEndDate?.ToShortDateString() ?? "N/A")</td>
                      <td>@(product.DiscontinuedDate?.ToShortDateString() ?? "N/A")</td>
                      <td>@product.ThumbnailPhotoFileName</td>
                      <td>@product.RowGuid</td>
                      <td>@product.ModifiedDate.ToShortDateString()</td>
                  </tr>
              }
          </tbody>
      </table>
    }
    
    @code {
    
      private Product[]? products;
    
      protected override async Task OnInitializedAsync()
      {
          products = await ProductApi.GetProductAsync();
      }
    
      private string GetImageString(byte[]? imageData)
      {
          if (imageData == null || imageData.Length == 0)
          {
              return "";
          }
          //It is almost always better to store images and files outside of the database.
          return String.Concat("data:image/png;base64,", Convert.ToBase64String(imageData, 0, imageData.Length));
      }
    }
    
  9. ในAspireSample.Webโครงการ ให้ขยายโฟลเดอร์เค้าโครงคอมโพเนนต์>

  10. เปิด NavMenu.razor

  11. ค้นหารหัสต่อไปนี้:

    <div class="nav-item px-3">
      <NavLink class="nav-link" href="weather">
          <span class="bi bi-list-nested" aria-hidden="true"></span> Weather
      </NavLink>
    </div>
    
  12. ทันทีหลังจากรหัสนั้น ให้เพิ่มบรรทัดต่อไปนี้:

    <div class="nav-item px-3">
      <NavLink class="nav-link" href="products">
          <span class="bi bi-list-nested" aria-hidden="true"></span> Products
      </NavLink>
    </div>
    
  13. หากต้องการบันทึกการเปลี่ยนแปลง ให้เลือก ไฟล์บันทึก>ทั้งหมด

เรียกใช้และทดสอบแอปในเครื่อง

แอปตัวอย่างพร้อมที่จะทดสอบแล้ว

  1. ใน Visual Studio Code กด F5 เพื่อเปิดแดชบอร์ดโครงการ .NET Aspire ของคุณในเบราว์เซอร์

  2. แท็บใหม่จะเปิดขึ้นเพื่อขอให้คุณลงชื่อเข้าใช้ Azure พร้อมท์คือการรับรองความถูกต้องกับฐานข้อมูล SQL ของคุณ เมื่อต้องการปรับใช้แอปพลิเคชันนี้ ให้ใช้บริการหรือข้อมูลประจําตัวที่มีการจัดการที่ผู้ใช้กําหนดหรือบริการหลัก หากต้องการเปลี่ยนประเภทการรับรองความถูกต้อง ให้อัปเดตสตริงการเชื่อมต่อของคุณ:

    สตริงการเชื่อมต่อแบบไม่ใช้รหัสผ่านตั้งค่าการกําหนดค่า Authentication="Active Directory Default"ซึ่งสั่งให้ Microsoft.Data.SqlClient ไลบรารีเชื่อมต่อกับฐานข้อมูล Azure SQL โดยใช้คลาสที่เรียกว่า DefaultAzureCredential. DefaultAzureCredential เปิดใช้งานการเชื่อมต่อแบบไม่ใช้รหัสผ่านกับบริการ Azure และจัดทําโดยไลบรารีข้อมูลประจําตัว Azure ที่ไลบรารีไคลเอ็นต์ SQL ขึ้นอยู่กับ DefaultAzureCredential รองรับวิธีการตรวจสอบสิทธิ์หลายวิธีและกําหนดวิธีการที่จะใช้ขณะรันไทม์สําหรับสภาพแวดล้อมที่แตกต่างกัน

    Note

    สตริงการเชื่อมต่อแบบไม่ใช้รหัสผ่านนั้นปลอดภัยที่จะผูกมัดกับการควบคุมแหล่งที่มา เนื่องจากไม่มีข้อมูลลับ เช่น ชื่อผู้ใช้ รหัสผ่าน หรือคีย์การเข้าถึง

  3. เลือกวงกลมสีแดงที่มีตัวเลขอยู่ถัดจากสถานะสําหรับ apiservice การดําเนินการนี้จะเปิดบันทึกข้อผิดพลาดพร้อมรายการสําหรับแต่ละครั้งที่การเชื่อมต่อฐานข้อมูลหมดเวลาในขณะที่รอข้อมูลประจําตัว

    ภาพหน้าจอของแอปพลิเคชัน Aspire พร้อมการแจ้งเตือนข้อผิดพลาดสีแดง

  4. เลือกปุ่มย้อนกลับในเบราว์เซอร์ของคุณเพื่อกลับไปที่แท็บทรัพยากร

  5. รอให้สถานะของเว็บฟรอนต์เอนด์เปลี่ยนเป็นกําลังทํางาน จากนั้นเลือก URL

  6. เลือกหน้า ผลิตภัณฑ์ ใหม่ในแถบนําทาง

  7. เลื่อนดูผลิตภัณฑ์ ผลิตภัณฑ์บางรายการมีรูปภาพในขณะที่ผลิตภัณฑ์อื่นๆ แสดงรูปภาพ "ไม่มีรูปภาพ"

    ภาพหน้าจอของรายการผลิตภัณฑ์แอปพลิเคชัน Aspire พร้อมรูปภาพผลิตภัณฑ์ต่างๆ

เพิ่มคุณสมบัติ

ไปต่อ!