ASP.MVC:反映IQueryable但不反映到SQL,DDD的Linq的存储库 [英] ASP.MVC: Repository that reflects IQueryable but not Linq to SQL, DDD How To question

查看:77
本文介绍了ASP.MVC:反映IQueryable但不反映到SQL,DDD的Linq的存储库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个DDD存储库,该存储库将返回与Linq匹配到SQL基础类的IQueryable实体,减去任何关系.我可以轻松地返回实体,并使用Linq选择新的{field,field,...}投影来减去关系.如何编写存储库实体类?如何从存储库中返回具有存储库类而不是Linq到SQL类的对象,并仍然用Linq选择中的多个实体填充该对象?我如何在ViewModel中引用此返回的类?

I want to create a DDD repository that returns IQueryable Entities that match the Linq to SQL underlying classes, minus any relations. I can easily return Entities minus the relations with a Linq select new {field, field, ... } projection. How do I code the Repository Entity class? How would I return an object from the repository having the repository class not the Linq to SQL class and still fill it with multiple entities from the Linq selection? How would I reference this returned class in my ViewModel?

我对此很陌生,因此是明显的错误.我是否想念船,应该只从存储库返回完整的实体,而不是投影?从存储库发送Linq与SQL的关系之前,我仍然需要删除它们.我完全不在基地了吗?我真的很想保留IQueryable数据类型.

I am very new to this, thus the obvious mistakes. Am I missing the boat and should only return complete Entities from the repository, not a projection? I would still need to strip out the Linq to SQL relations before I send them from the repository. Am I totally off base? I really want to keep the IQueryable data type.

例如,我的存储库中的Linq to SQL代码:

For example, my Linq to SQL code in my repository:

public class MiniProduct
{
    public MiniProduct( string ProductNo, string Name, string Description, double Price)
    {    this.ProductNo = ProductNo;
         this.Name = Name;
         this.Description = Description;
         this.Price = Price;
    }
}

public IQueryable<MiniProduct> GetProductsByCategory( string productCategory)
{
    return ( from p in db.Products
             from c in db.Categories
             from pc in db.ProductCategories
             where c.CategoryName == productCategory &&
                   c.CatID == pc.CatID &&
                   pc.ProductID == p.ProductID
             select new { p.ProductNo, p.Name, p.Description, p.Price } );
    // how to return IQueryable<MiniProduct> instead of IQueryable<AnonymousType>???
}

在视图中(试图强力键入ViewModel),我的模型数据类型是什么,以及如何从视图中引用?

And in the View (trying to strongly type ViewModel) what would be my model data type and how to reference from the view?

<% Page Inherits="System.Web.Mvc.ViewPage<MyStore.Models.MiniProduct>" %>

Cottsak授权并使其生效,因此他赢得了该复选框.但是,马克·西曼(Mark Seemann)指出,这种技术会引起副作用.他说对了,对POCO进行投影或设置很糟糕,这是正确的.使代码正常工作后,我最终从实体对象中多了一个对象,这造成了不必要的复杂性.最终,我更改了代码以反映Mark的建议.

Cottsak empowered the code and made it work, so he earns the checkbox. However, Mark Seemann pointed out that this technique will cause side effects. He was right in that projecting or sub-setting your POCO is bad. After making the code work, I ended up making a ton more one off entity objects, which causes unnecessary complications. Ultimately I changed the code to reflect Mark's suggestions.

要添加到Cottsak的建议中:我的存储库返回值为IQueryable.页面指​​令模型引用类型为

To add to Cottsak's suggestions: My repository return value was IQueryable. The page directive model reference type was

Inherits="System.Web.Mvc.ViewPage<IQueryable<MyStore.Models.MiniProduct>>"

通过以下方式访问模型"字段:

The Model fields were accessed by:

Model.SingleOrDefault().ProductNo
Model.SingleOrDefault().Name
...

这导致了

foreach (MyStore.Models.MiniProduct myproduct in Model) {}

谢谢你们的回答.

推荐答案

尝试如下操作:

public class AnnouncementCategory : //...
{
    public int ID { get; set; }
    public string Name { get; set; }
}

..和您的回购中:

public IQueryable<AnnouncementCategory> GetAnnouncementCategories()
{
    return from ac in this._dc.AnnouncementCategories
           let announcements = this.GetAnnouncementsByCategory(ac.ID)
           select new AnnouncementCategory
           {
               ID = ac.ID,
               Name = ac.Text,
               Announcements = new LazyList<Announcement>(announcements)
           };
}

private IQueryable<Announcement> GetAnnouncementsByCategory(int categoryID)
{
    return GetAnnouncements().Where(a => a.Category.ID == categoryID);
}

这样,我将投影到我的AnnouncementCategory类的新实例中,而不是投影成匿名类型.如果愿意,您可以忽略GetAnnouncementsByCategory函数,该函数用于为每个类别链接关联的Announcement对象的集合,但以某种方式可以使它们被IQueryable延迟加载(即,当我执行最终调用此属性,而不必调用整个集合.我可以对此进行更多的LINQ过滤).

This way, instead of projecting into an anonymous type, i'm projecting into a new instance of my AnnouncementCategory class. You can ignore the GetAnnouncementsByCategory function if you like, this is used to chain the collection of associated Announcement objects for each category but in a way so that they can be lazy loaded with IQueryable (ie. so that when i do eventually call on this property, i don't have to call the entire collection. i can do more LINQ on this to filter).

这篇关于ASP.MVC:反映IQueryable但不反映到SQL,DDD的Linq的存储库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆