سؤال

لعدة أسباب لا أملك الحرية في الحديث عنها، فإننا نقوم بتعريف طريقة عرض في قاعدة بيانات Sql Server 2005 الخاصة بنا كما يلي:

CREATE VIEW [dbo].[MeterProvingStatisticsPoint]
AS
SELECT
    CAST(0 AS BIGINT) AS 'RowNumber',
    CAST(0 AS BIGINT) AS 'ProverTicketId',
    CAST(0 AS INT) AS 'ReportNumber',
    GETDATE() AS 'CompletedDateTime',
    CAST(1.1 AS float) AS 'MeterFactor',
    CAST(1.1 AS float) AS 'Density',
    CAST(1.1 AS float) AS 'FlowRate',
    CAST(1.1 AS float) AS 'Average',
    CAST(1.1 AS float) AS 'StandardDeviation',
    CAST(1.1 AS float) AS 'MeanPlus2XStandardDeviation',
    CAST(1.1 AS float) AS 'MeanMinus2XStandardDeviation'
WHERE 0 = 1

الفكرة هي أن Entity Framework سيقوم بإنشاء كيان بناءً على هذا الاستعلام، وهو ما يفعله، ولكنه ينشئه مع وجود خطأ ينص على ما يلي:

تحذير 6002:لا يحتوي الجدول/العرض 'Keystone_Local.dbo.MeterProvingStatisticsPoint' على مفتاح أساسي محدد.تم استنتاج المفتاح وتم إنشاء التعريف كجدول/عرض للقراءة فقط.

ويقرر أن الحقل CompletedDateTime سيكون هو المفتاح الأساسي لهذا الكيان.

نحن نستخدم EdmGen لإنشاء النموذج.هل هناك طريقة لعدم تضمين إطار عمل الكيان أي مجال من مجالات العرض هذه كمفتاح أساسي؟

هل كانت مفيدة؟

المحلول

وكان لدينا نفس المشكلة وهذا هو الحل:

لإجبار إطار كيان لاستخدام عمود كمفتاح أساسي، استخدم ISNULL.

لإجبار إطار كيان بعدم استخدام عمود كمفتاح أساسي، استخدم NULLIF.

وطريقة سهلة لتطبيق هذا هو التفاف العبارة حدد من وجهة نظركم في اختيار آخر.

مثال:

SELECT
  ISNULL(MyPrimaryID,-999) MyPrimaryID,
  NULLIF(AnotherProperty,'') AnotherProperty
  FROM ( ... ) AS temp

نصائح أخرى

لقد تمكنت من حل هذه المشكلة باستخدام المصمم.

  1. افتح متصفح النماذج.
  2. ابحث عن العرض في الرسم التخطيطي.
  3. انقر بزر الماوس الأيمن على المفتاح الأساسي، وتأكد من تحديد "Entity Key".
  4. تحديد متعدد لجميع المفاتيح غير الأساسية.استخدم مفاتيح Ctrl أو Shift.
  5. في نافذة الخصائص (اضغط على F4 إذا لزم الأمر لرؤيتها) ، قم بتغيير "مفتاح الكيان" المنسدلة إلى كاذبة.
  6. حفظ التغييرات.
  7. أغلق Visual Studio وأعد فتحه.أنا أستخدم Visual Studio 2013 مع EF 6 واضطررت إلى القيام بذلك للحصول على التحذيرات للخروج.

لم أضطر إلى تغيير طريقة العرض لاستخدام الحلول البديلة ISNULL أو NULLIF أو COALESCE.إذا قمت بتحديث النموذج الخاص بك من قاعدة البيانات، فستظهر التحذيرات مرة أخرى، ولكنها ستختفي إذا قمت بإغلاق VS وإعادة فتحه.سيتم الحفاظ على التغييرات التي أجريتها في المصمم ولن تتأثر بالتحديث.

ونتفق معTillito، ولكن في معظم الحالات، سوف كريهة SQL محسن وأنها لن تستخدم المؤشرات الصحيحة.

قد يكون واضحا لشخص ما، ولكن أنا أحرق ساعات حل مشكلات الأداء باستخدام محلول Tillito. دعونا نقول لديك الجدول:

 Create table OrderDetail
    (  
       Id int primary key,
       CustomerId int references Customer(Id),
       Amount decimal default(0)
    );
 Create index ix_customer on OrderDetail(CustomerId);

ووجهة نظرك هو شيء من هذا القبيل

 Create view CustomerView
    As
      Select 
          IsNull(CustomerId, -1) as CustomerId, -- forcing EF to use it as key
          Sum(Amount) as Amount
      From OrderDetail
      Group by CustomerId
سوف

وSQL محسن عدم استخدام مؤشر ix_customer وأنه سيتم تنفيذ مسح الجدول على فهرس أساسي، ولكن إذا بدلا من:

Group by CustomerId

وكنت تستخدم

Group by IsNull(CustomerId, -1)

وسيجعل MS SQL (على الأقل 2008) تشمل مؤشر الحق في الخطة.

إذا

وهذا الأسلوب يعمل بشكل جيد بالنسبة لي. يمكنني استخدام ISNULL () لحقل المفتاح الأساسي، وتلتحم () إذا يجب مجال لا يكون المفتاح الأساسي، ولكن ينبغي أيضا أن يكون لها قيمة غير قيم الفارغة. ينتج هذا المثال حقل معرف مع مفتاح أساسي غير قابل للقيم الفارغة. الحقول الأخرى ليست مفاتيح، ولها (لا يوجد) كما سمة من Nullable و.

SELECT      
ISNULL(P.ID, - 1) AS ID,  
COALESCE (P.PurchaseAgent, U.[User Nickname]) AS PurchaseAgent,  
COALESCE (P.PurchaseAuthority, 0) AS PurchaseAuthority,  
COALESCE (P.AgencyCode, '') AS AgencyCode,  
COALESCE (P.UserID, U.ID) AS UserID,  
COALESCE (P.AssignPOs, 'false') AS AssignPOs,  
COALESCE (P.AuthString, '') AS AuthString,  
COALESCE (P.AssignVendors, 'false') AS AssignVendors 
FROM Users AS U  
INNER JOIN Users AS AU ON U.Login = AU.UserName  
LEFT OUTER JOIN PurchaseAgents AS P ON U.ID = P.UserID

وإذا كنت حقا لم يكن لديك مفتاح أساسي، يمكنك محاكاة ساخرة واحد باستخدام ROW_NUMBER لتوليد مفتاح الزائفة التي تجاهلها من قبل التعليمات البرمجية. على سبيل المثال:

SELECT
ROW_NUMBER() OVER(ORDER BY A,B) AS Id,
A, B
FROM SOMETABLE

ومولد إطار الكيان EDM الحالي سيخلق مفتاح مركب من جميع المجالات غير قيم الفارغة في وجهة نظركم. من أجل السيطرة على هذا، سوف تحتاج إلى تعديل طريقة العرض وأعمدة الجدول الكامنة وراء وضع الأعمدة لقيم الفارغة عندما كنت لا تريد لها أن تكون جزءا من المفتاح الأساسي. والعكس صحيح أيضا، كما أنني واجهت، إنشاء EDM مفتاح كان يسبب القضايا ازدواجية البيانات، لذلك اضطررت لتحديد عمود قيم الفارغة على أنها غير nullable لإجبار مفتاح مركب في EDM لتشمل هذا العمود.

ويبدو أنها مشكلة معروفة EdmGen: <لأ href = "http://social.msdn.microsoft.com/forums/en-US/adodotnetentityframework/thread/12aaac4d-2be8-44f3-9448-d7c659585945/ "يختلط =" noreferrer نوفولو "> http://social.msdn.microsoft.com/forums/en-US/adodotnetentityframework/thread/12aaac4d-2be8-44f3-9448-d7c659585945/

للحصول على عرض اضطررت الى المعرض الوحيد <م> واحدة عمود المفتاح الأساسي وما خلقت نظرة الثاني الذي أشار إلى NULLIF الأول والتي استخدمت لصنع أنواع nullable. عملت هذا بالنسبة لي لجعل EF يعتقدون كان هناك مجرد مفتاح أساسي واحد في طريقة العرض.

وليس متأكدا مما إذا كان هذا سيساعدك على الرغم منذ أنا لا أعتقد أن EF يقبل كيان مع NO المفتاح الأساسي.

وأوصي أيضا إذا كنت لا تريد الفوضى مع ما ينبغي أن يكون المفتاح الأساسي لدمج ROW_NUMBER لاختيار وتعيين أنها المفتاح الأساسي وتعيين كافة الأعمدة / بواسطة أعضاء آخرين على أنها غير الابتدائي في النموذج.

ونظرا للمشاكل المذكورة أعلاه، لكنني أفضل ظائف قيمة الجدول.

إذا كان لديك هذا:

CREATE VIEW [dbo].[MyView] AS SELECT A, B FROM dbo.Something

وإنشاء هذا:

CREATE FUNCTION MyFunction() RETURNS TABLE AS RETURN (SELECT * FROM [dbo].[MyView])

وبعد ذلك يمكنك ببساطة استيراد وظيفة بدلا من طريقة العرض.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top