2012-10-09 22 views
6

के कॉलम में मैप किए गए एंटिटी रीड-ओनली प्रॉपर्टी में मुझे हल करने में दिलचस्प समस्या है, लेकिन हालांकि, आम है, ऐसा लगता है कि यह एंटिटी फ्रेमवर्क के साथ आसानी से प्राप्त नहीं किया जा सकता है। दो टेबल हैं:इकाई फ्रेमवर्क - संबंधित तालिका

Player(Id,TeamId,FirstName,LastName) 
Team(Id, Name, IsProfessional) 

प्लेयर केवल एक टीम से संबंधित हो सकता है। का उपयोग करते हुए टीपीटी (DB पहले), हम दो वर्गों उन तालिकाओं को मैप किया है

public class Player 
{ 
    public int Id{get;set;} 
    public int TeamId{get;set;} 
    public string FirstName{get; set;} 
    public string LastName{get; set;} 
    public Team Team{get;set;} 
} 

public class Team 
{ 
    public int Id{get; set;} 
    public string Name{get;set;} 
    public bool IsProfessional{get;set;} 
    public IEnumerable<Player> Players{get;} 
} 

मैं प्राप्त करने के लिए चाहते हैं क्या प्लेयर इकाई पर संपत्ति IsProfessional है:

public class Player 
    { 
     public int Id{get;set;} 
     public int TeamId{get;set;} 
     public string FirstName{get; set;} 
     public string LastName{get; set;} 
     public Team Team{get;set;} 
     **public bool IsProfessional{get;}** should be read-only 
    } 

यह मानचित्रण कॉन्फ़िगर करने के लिए संभव है कि रास्ता क्या व्यावसायिक संपत्ति linq प्रश्नों में इस्तेमाल किया जा सकता है?

var result= db.Players.Where(p=>p.IsProfessional==true); 

और उस क्षेत्र आबादी वाले हर बार प्लेयर इकाई materialized है के लिए?

  • इकाई विभाजन:

    Player pl = db.Players.Where(p=>p.FirstName="Lionel").FirstOrDefault(); 
    if(pl.IsProfessional) 
    { 
    //do something... 
    } 
    

    पहले से ही साथ की कोशिश की। संभव नहीं है क्योंकि मैं टीम मैपिंग रखना चाहता हूं और क्योंकि रिश्ते 1: 1 नहीं है)

  • मैपिंग प्लेयर इकाई को डीबी व्यू पर मैप करना। इसे पसंद नहीं आया क्योंकि अन्य संबंध हैं प्लेयर इकाई की मुझे आवश्यकता है। मुझे पता है कि उन्हें मैन्युअल रूप से बनाना संभव है, लेकिन डेटाबेस से edmx को अद्यतन करना ssdl को रीसेट करेगा।

धन्यवाद

समाधान

गर्ट अर्नोल्ड जवाब में दूसरा विकल्प, समाधान है कि मेरी जरूरतों फिट बैठता है के आधार पर इस प्रकार है:

  1. मैं समारोह GetIsProfessional बनाने (पड़ा ऐसा करें क्योंकि गणना किए गए फ़ील्ड सामान्य रूप से केवल अपने टेबल फ़ील्ड से ही किए जा सकते हैं)

    CREATE FUNCTION [dbo].[GetIsProfessional](@teamId as INT) 
    RETURNS bit 
    
    BEGIN 
    
    DECLARE @isProfi AS bit 
    
    SELECT @isProfi = IsProfessional 
    FROM Teams 
    WHERE Id = @teamId 
    
    RETURN @isProfi 
    
    END 
    
  2. मैं Player मेज पर गणना क्षेत्र बनाया

    ALTER TABLE Players ADD [IsProfessional] AS dbo.GetIsProfessional(TeamId) 
    
  3. मैं db पहले दृष्टिकोण का उपयोग कर रहा हूँ के रूप में, मैं सिर्फ डेटाबेस से मॉडल को अद्यतन करने और है कि, यह मुझे लगता है कि मैदान पर क्वेरी कर सकता है और यह पूर्व आबादी वाले है जब प्लेयर ऑब्जेक्ट भौतिक हो जाता है।

+0

तो 'प्लेयर.इस्प्रोफेशनल' को 'प्लेयर.इम.इज प्रोफेशनल' के समान परिणाम देना चाहिए? ईएफ वर्तमान में उन गुणों का समर्थन नहीं करता है जो एक साधारण डेटाबेस फ़ील्ड को मैप नहीं करते हैं, क्षमा करें, लेकिन शायद कोई एक अच्छा विकल्प के साथ जवाब देगा। – hvd

+0

प्लेयर को छोड़कर मुझे वही चाहिए जो कि आवश्यक है। व्यावसायिक व्यवसाय केवल पढ़ा जाना चाहिए। मेरे द्वारा खोजे जाने वाले सभी विकल्प वास्तव में अच्छे नहीं हैं। –

उत्तर

8

यह एफई के साथ नहीं किया जा सकता है।वहाँ कुछ विकल्प है कि ऐसा नहीं करते हैं तो आप वास्तव में क्या चाहते हैं, लेकिन मिल रहे हैं पास और अधिक या कम:

  1. अपने संदर्भ में एक संपत्ति TeamPlayers कि रिटर्न टीम के साथ खिलाड़ियों को शामिल बनाएं, ताकि आप हमेशा क्या कर सकते हैं player.Team.IsProfessional तब भी जब संदर्भ पहले से ही हटा दिया गया है।

    public IQueryable<PLayer> TeamPlayers 
    { 
        get { return this.Players.Include("Team"); } 
    } 
    
  2. डेटाबेस तालिका में परिकलित फ़ील्ड बनाएं और DatabaseGeneratedOption.Computed साथ यह करने के लिए नक्शे।

  3. Player कि अभिव्यक्ति है कि Team.IsProfessional तक पहुँचता रिटर्न में एक स्थिर संपत्ति बनाएँ (एक जीवित संदर्भ की आवश्यकता है या टीम शामिल है):

    public static Expression<Func<PLayer, bool>> IsProfessional 
    { 
        get { return p => p.Team.IsProfessional; } 
    } 
    ... 
    db.Players.Where(p=> p.FirstName="Lionel").Where(Player.IsProfessional).... 
    

मैं, गणना क्षेत्र पसंद करेंगे हमेशा आबादी है, क्योंकि यह , तो आप इसे संदर्भ के दायरे के अंदर और बाहर उपयोग कर सकते हैं।

+0

बढ़िया! परिकलित क्षेत्र मेरी आवश्यकताओं को सर्वोत्तम बनाता है: 1) मैं गणना वाले क्षेत्र पर क्वेरी कर सकता हूं, 2) यह अन्य प्लेयर गुणों के साथ पॉप्युलेट किया गया है। आपका बहुत बहुत धन्यवाद! –

0

क्या होगा यदि आप खिलाड़ी को टीम से खींचने वाली संपत्ति रखने के लिए विस्तारित करते हैं?

public partial class Player 
{ 
    public int Id{get;set;} 
    public int TeamId{get;set;} 
    public string FirstName{get; set;} 
    public string LastName{get; set;} 
    public Team Team{get;set;} 

    public bool IsProfessional{ get { return Team.IsProfessional; } } 
} 
बेशक

, यदि आप अपने edmx पुनः बारे में चिंतित हैं, आप इसे एक आंशिक बना सकते हैं:

public partial class Player 
{ 
    public bool IsProfessional{ get { return Team.IsProfessional; } } 
} 
+0

हां, लेकिन इस तरह प्लेयर। यह पेशेवर linq प्रश्नों में प्रयोग योग्य नहीं है (जैसा कि मैंने प्रश्न में बताया है)। साथ ही, जब प्रॉपर्टी प्लेयर.इस्प्रोफेशनल एक्सेस किया जाता है तो यह डीबी से एक बूलियन प्राप्त करने के लिए एसक्यूएल क्वेरी करेगा। मैं पसंद करूंगा कि वह बुलियन एक ही समय में अन्य सभी प्लेयर गुणों के रूप में भर जाता है। –

0

आप System.ComponentModel.DataAnnotations.Schema.NotMappedAttribute उपयोग कर सकते हैं IsProfessional संपत्ति इस तरह की मैपिंग को रोकने के लिए:

// Mapped part of entity 
public class Player 
{ 
    public int Id { get; set; } 
    public int TeamId { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public Team Team { get; set; } 
} 

// Unmapped part of entity 
using System.ComponentModel.DataAnnotations.Schema; 
... 
public partial class Player 
{ 
    [NotMapped()] 
    public bool IsProfessional { get { /* ... IsProfessional calculation logic comes here ... */ } } 
} 

मैं में EF5's Model First दृष्टिकोण इस विशेषता का इस्तेमाल किया और मैं DbContext/DbSet से अधिक पूछे और ObjectContext/ObjectQuery बिना किसी अपवाद के। (100% परीक्षण)

+0

ठीक है, लेकिन यह संपत्ति इस इकाई से बनाए गए डेटासोर्स I में दिखाई नहीं देती है। –

+0

मैं आमतौर पर ऑब्जेक्टडेटा स्रोत का उपयोग करता हूं और यह मेरी इकाई कक्षाओं के सभी सार्वजनिक गुण दिखाता है। मुझे लगता है कि EntityDataSource केवल .edmx फ़ाइल में उनकी स्कीमा घोषणा के कारण जेनरेट की गई इकाइयों के मैप किए गए गुणों को पढ़ता है। – Perseus

+0

क्या यह काम करता है? – Worthy7

संबंधित मुद्दे