วิธีใช้มุมมองในกรอบเอนทิตีโค้ดแรก [ปิด]


87

ฉันจะใช้มุมมองฐานข้อมูลในรหัสกรอบงานเอนทิตีก่อนได้อย่างไร


2
ไม่มีคำตอบใดด้านล่างอธิบายวิธีสร้างมุมมองโดยใช้การย้ายข้อมูล EF ดูคำตอบนี้สำหรับคำถามที่คล้ายกัน
Rudey

นี่คือชุดข้อความที่มีคำถามเดียวกัน - stackoverflow.com/questions/13593845/…
Div Tiwari

ลองของฉันวิธีการแก้ปัญหา ป้องกันการสร้างการโยกย้ายสำหรับตารางที่ทำเครื่องหมายเป็นมุมมอง
kogoia

คำตอบ:


95

หากเช่นฉันคุณสนใจเฉพาะเอนทิตีการแมปที่มาจากฐานข้อมูลอื่น (erp ในกรณีของฉัน) เพื่อเชื่อมโยงพวกเขากับเอนทิตีเฉพาะของแอปพลิเคชันของคุณคุณสามารถใช้มุมมองในขณะที่คุณใช้ตาราง (แมปมุมมองใน ในลักษณะเดียวกัน!) เห็นได้ชัดว่าหากคุณพยายามอัปเดตเอนทิตีนั้นคุณจะได้รับข้อยกเว้นหากไม่สามารถอัปเดตมุมมองได้ ขั้นตอนนี้เหมือนกับในกรณีของเอนทิตีปกติ (ตามตาราง):

  1. สร้างคลาส POCO สำหรับมุมมอง ตัวอย่างเช่น FooView
  2. เพิ่มคุณสมบัติ DbSet ในคลาส DbContext
  3. ใช้ไฟล์ FooViewConfiguration เพื่อตั้งชื่ออื่นสำหรับมุมมอง (โดยใช้ ToTable ("Foo") ในตัวสร้าง) หรือเพื่อตั้งค่าคุณสมบัติเฉพาะ

    public class FooViewConfiguration : EntityTypeConfiguration<FooView>      
    {
        public FooViewConfiguration()
        {
            this.HasKey(t => t.Id);
            this.ToTable("myView");
        }
    }
    
  4. เพิ่มไฟล์ FooViewConfiguration ไปยัง modelBuilder ตัวอย่างเช่นการวางไข่ของเมธอด OnModelCreating ของ Context:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Configurations.Add(new FooViewConfiguration ());
    }
    

64
+1 โดยไม่คิดว่า "Code First" == การสร้างฐานข้อมูลอัตโนมัติ
onetwopunch

3
@DaveJellison คุณต้องการที่จะอธิบายอย่างละเอียดหรือให้ลิงค์เกี่ยวกับการเพิ่มมุมมองเป็นส่วนหนึ่งของ IDatabaseInitializer
Ralph Shillington

19
เป็นเพียงฉันหรือทุกคนได้รับตารางว่างที่สร้างขึ้นโดยการย้าย มีวิธีหลีกเลี่ยงหรือไม่?
Kremena Lalova

4
ตรวจสอบให้แน่ใจที่นี่โซลูชันนี้ต้องการให้เราสร้าง View บนฐานข้อมูล SQL ก่อนภายนอกหรือไม่ เป็นไปได้หรือไม่ที่จะกำหนดมุมมองในโค้ดและเติมข้อมูลลงในฐานข้อมูลผ่านคำสั่ง Add-Migration / Update-Database
น้ำค้าง

6
บางสิ่ง. 1. คำตอบนี้ไม่ได้กล่าวถึงคุณต้องสร้างมุมมองด้วยตนเองโดยใช้ SQL ซึ่งสามารถทำได้โดยใช้การโยกย้าย 2. คุณไม่จำเป็นต้องกำหนดค่าชื่อมุมมองหากชื่อคลาสตรงกับชื่อมุมมอง 3. คุณสามารถใช้ DataAnnotations ได้ดังนี้[Table("myView")]เนื้อหานี้ง่ายกว่าการสร้างไฟล์EntityTypeConfiguration.
Rudey

23

นี่อาจเป็นการอัปเดต แต่หากต้องการใช้มุมมองกับ EF Code ก่อนอื่นให้เพิ่ม [Table ("NameOfView")] ที่ด้านบนสุดของชั้นเรียนและทั้งหมดนี้ควรใช้งานได้ทันทีโดยไม่ต้องผ่านห่วงทั้งหมด นอกจากนี้คุณจะต้องรายงานคอลัมน์ใดคอลัมน์หนึ่งเป็นคอลัมน์ [คีย์] นี่คือโค้ดตัวอย่างของฉันด้านล่างเพื่อใช้งาน

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace SomeProject.Data
{
    [Table("SomeView")]
    public class SomeView
    {
        [Key]
        public int NameID { get; set; }
        public string Name { get; set; }
    }
}

และนี่คือลักษณะของบริบท

using System.Data.Entity;

namespace SomeProject.Data
{
    public class DatabaseContext : DbContext
    {
        public DbSet<SomeView> SomeViews { get; set; }
    }
}

2
คำตอบนี้เหมือนกับคำตอบที่ยอมรับยกเว้นว่าจะใช้ DataAnnotations ในขณะที่คำตอบที่ยอมรับจะใช้ EF Fluid API
Rudey

4
จริงๆแล้วมันไม่ใช่ ฉันพยายามโดยไม่ประสบความสำเร็จกับคำตอบที่ยอมรับและมันก็ไม่ได้ผลสำหรับฉัน แต่ตอนนั้นฉันกำลังใช้การโยกย้ายดังนั้นสิ่งนี้อาจส่งผลกระทบต่อสิ่งต่างๆ ฉันพบว่าฉันต้องทำการโยกย้ายก่อนจากนั้นจึงเพิ่มคลาสมุมมองของฉันเนื่องจากมีอยู่แล้วในฐานข้อมูล เราจะจัดการมันในลักษณะเดียวกันถ้าเรามีตารางอยู่แล้วในฐานข้อมูล เนื่องจากมุมมองเป็น "ตารางเสมือน" ไวยากรณ์ของตารางใน Entity Framework ยังคงใช้งานได้
Charles Owen

12

หากสิ่งที่คุณต้องการคืออ็อบเจ็กต์ de-normalized จำนวนมากคุณอาจสร้างIQueryable<TDenormolized>คุณสมบัติรับอย่างเดียวสาธารณะในDbContextคลาสของคุณ

ในการgetส่งคืนผลลัพธ์ Linq เพื่อฉายค่า de-normoalized ลงในอ็อบเจ็กต์ de-normalized ของคุณ สิ่งนี้อาจดีกว่าการเขียน DB View เนื่องจากคุณกำลังเขียนโปรแกรมคุณไม่ได้ถูก จำกัด ด้วยการใช้selectคำสั่งเท่านั้น นอกจากนี้ยังรวบรวมประเภทเวลาที่ปลอดภัย

เพียงระวังอย่าเรียกการแจงนับเช่นการToList()โทรซึ่งจะทำลายการสืบค้นที่รอการตัดบัญชีและคุณอาจได้รับข้อมูลจำนวนหนึ่งล้านรายการกลับจากฐานข้อมูลและกรองข้อมูลเหล่านั้นบนแอปพลิเคชันเซิร์ฟเวอร์ของคุณ

ฉันไม่รู้ว่านี่เป็นวิธีที่ถูกต้องหรือเปล่า แต่ฉันลองแล้วมันก็ใช้ได้


6
เหตุผลประการหนึ่งที่ฉันต้องการใช้มุมมองคือ SQL ที่สร้างขึ้นโดย EF นั้นไม่ 'ดี' เสมอไป - เรามีลำดับชั้นการสืบทอดในแบบจำลองของเรา (พบว่ามีข้อผิดพลาดที่สายเกินไป ... ) และการใช้มุมมองช่วยให้เรา เพื่อสร้าง SQL ด้วยตนเอง เพียงแค่ความแตกต่างว่าทำไมมุมมองจึงเป็นที่ต้องการ
Carl

2
เหตุผลอื่นที่ไม่ทำเช่นนี้อาจเป็นการใช้นิพจน์ตารางทั่วไปแบบเรียกซ้ำซึ่งไม่มีใน LINQ แต่อย่างอื่นนี่เป็นคำแนะนำที่ดีสำหรับสถานการณ์ที่ง่ายกว่า
Tom Pažourek

1
การใช้คุณสมบัติแทนมุมมองไม่ใช่ตัวเลือกหากคุณต้องการใช้ประโยชน์จากมุมมองที่จัดทำดัชนี
Rudey

"คุณไม่ได้ถูก จำกัด ด้วยการใช้คำสั่งที่เลือกเท่านั้น" คุณหมายถึงอะไร? สิ่งที่คุณสามารถทำได้ด้วย LINQ สามารถทำได้โดยใช้คำสั่ง SELECT ซึ่งไม่สามารถพูดได้เช่นเดียวกันในทางกลับกัน
Rudey

3

ฉันรู้ว่านี่เป็นคำถามเก่าและมีคำตอบมากมายที่นี่ แต่ฉันถูกบังคับให้เกิดปัญหาเมื่อฉันใช้คำตอบนี้และเกิดข้อผิดพลาดเมื่อฉันใช้คำสั่ง update-database ใน Package Manager Console:

มีวัตถุชื่อ "... " อยู่แล้วในฐานข้อมูล

และฉันใช้ขั้นตอนเหล่านี้เพื่อแก้ไขปัญหานี้:

  1. รันคำสั่งนี้ใน Package Manager Console: Add-migration intial
  2. ภายใต้โฟลเดอร์ Migrations คุณจะพบไฟล์ ..._ intial.cs เปิดและแสดงความคิดเห็นหรือลบคำสั่งใด ๆ ที่เกี่ยวข้องกับคลาสของคุณที่คุณต้องการแมป
  3. ตอนนี้คุณสามารถใช้คำสั่ง update-database สำหรับการเปลี่ยนแปลงอื่น ๆ ในโมเดลของคุณได้

หวังว่ามันจะช่วยได้


1
ขอบคุณ! สิ่งนี้ช่วยได้จริงๆ! นอกจากนี้แทนที่จะลบโค้ดที่สร้างด้วย EF Migrations คุณสามารถเพิ่มที่นั่นแทนได้migrationBuilder.Sql("CREATE OR REPLACE VIEW ...); เพื่อให้เพื่อนร่วมงานสามารถใช้เพื่ออัปเกรดฐานข้อมูลได้
Rich_Rich
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.