5

मेरे पास एक एएसपी.नेट एमवीसी एप्लीकेशन है जो डेटा प्राप्त करने के लिए इकाई फ्रेमवर्क का उपयोग करता है।इकाई फ्रेमवर्क में अनुमानों का पुन: उपयोग कैसे करें?

मुझे देखने के लिए उन्हें पास करने से पहले एंटरसाइट्स को मॉडल में बदलने की आवश्यकता है। अनुमान बहुत जटिल हो सकता है, लेकिन यह सरल रखने के लिए:

public static IQueryable<UserModel> ToModel(this IQueryable<User> users) 
{ 
    return from user in users 
      select new UserModel 
      { 
       Name = user.Name, 
       Email = user.Email, 
      }; 
} 

यह इस तरह एक नियंत्रक में इस्तेमाल किया जा सकता है:

return View(Repository.Users.ToModel().ToList()); 

बहुत अच्छा। लेकिन क्या होगा यदि मैं इस प्रक्षेपण का उपयोग किसी और के अंदर करना चाहता हूं? उदाहरण:

public static IQueryable<BlogPostModel> ToModel(this IQueryable<BlogPost> blogs) 
{ 
    return from blogs in blogs 
      select new BlogPostModel 
      { 
       Title = blog.Title, 
       Authors = blog.Authors.AsQueryable().ToModel(), // (entities are POCOs) 
       // This does not work, because EF does not understand method ToModel(). 
      }; 
} 

(मान लीजिए कि ब्लॉग में एक लेखक हो सकता है और यह उपयोगकर्ता प्रकार का है)।

क्या मैं किसी भी तरह से अनुमानों को अलग कर सकता हूं और उन्हें किसी अन्य के अंदर पुन: उपयोग कर सकता हूं?

namespace Entities 
{ 
    public class BlogPost 
    { 
     public virtual int Id { get; set; } 
     public virtual string Title { get; set; } 
     public virtual DateTime Created { get; set; } 
     public virtual ICollection<User> Authors { get; set; } 
    } 

    public class User 
    { 
     public virtual int Id { get; set; } 
     public virtual string Name { get; set; } 
     public virtual string Email { get; set; } 
     public virtual byte[] Password { get; set; } 
     public virtual ICollection<BlogPost> BlogPosts { get; set; } 
    } 
} 

namespace Models 
{ 
    public class BlogPostModel 
    { 
     public string Title { get; set; } 
     public IEnumerable<UserModel> Authors { get; set; } 
    } 

    public class UserModel 
    { 
     public string Name { get; set; } 
     public string Email { get; set; } 
    } 

    public static class BlogPostModelExtensions 
    { 
     public static readonly Expression<Func<BlogPost, BlogPostModel>> ToModelConverterExpression = 
      p => 
      new BlogPostModel 
      { 
       Title = p.Title, 
       Authors = p.Authors.AsQueryable().Select(UserModelExtensions.ToModelConverterExpression), 
      }; 

     public static readonly Func<BlogPost, BlogPostModel> ToModelConverterFunction = ToModelConverterExpression.Compile(); 

     public static IQueryable<BlogPostModel> ToModel(this IQueryable<BlogPost> blogPosts) 
     { 
      return blogPosts.Select(ToModelConverterExpression); 
     } 

     public static IEnumerable<BlogPostModel> ToModel(this IEnumerable<BlogPost> blogPosts) 
     { 
      return blogPosts.Select(ToModelConverterFunction); 
     } 
    } 

    public static class UserModelExtensions 
    { 
     public static readonly Expression<Func<User, UserModel>> ToModelConverterExpression = 
      u => 
      new UserModel 
      { 
       Name = u.Name, 
       Email = u.Email, 
      }; 

     public static readonly Func<User, UserModel> ToModelConverterFunction = ToModelConverterExpression.Compile(); 

     public static IQueryable<UserModel> ToModel(this IQueryable<User> users) 
     { 
      return users.Select(ToModelConverterExpression); 
     } 

     public static IEnumerable<UserModel> ToModel(this IEnumerable<User> users) 
     { 
      return users.Select(ToModelConverterFunction); 
     } 
    } 
} 

वास्तव में एक डेटाबेस बनाने के बिना यह परीक्षण करने के लिए:

+1

http: // stackoverflow.com/a/11679134/861716। –

उत्तर

8

यहाँ कुछ है कि वास्तव में काम करता है (एक साधारण परीक्षण आवेदन में) केवल अनुरोध किया क्षेत्रों का चयन करने के लिए

var blogPostsQuery = (
    from p in context.BlogPosts 
    where p.Title.StartsWith("a") 
    select p).ToModel(); 
Console.WriteLine(((ObjectQuery)blogPostQuery).ToTraceString()); 
+3

अच्छा विचार! लेकिन मुझे लगता है कि यह "घोंसला" प्रक्षेपण नहीं है जो डेटाबेस में होता है। यह पूर्ण 'लेखक' इकाइयों को लोड करेगा और फिर स्मृति में सेटर में प्रोजेक्ट करेगा, यानी कुछ लोड किए गए कॉलम/गुणों को दूर या शायद फेंक दें। – Slauma

+0

@ स्लुमा ओह, आप सही हैं, मुझे याद आया। मैं थोड़ा सा सोचूंगा। – hvd

+0

यह संकलित करता है और सही ढंग से चलता है, लेकिन @ स्लुमा सही है .. मैंने प्रोफाइलर की जांच की और यह पूरे उपयोगकर्ता को डीबी से पुनर्प्राप्त करता है। आपको क्या लगता है, क्या यह सुलभ है? धन्यवाद! – jakubka

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