【问题标题】:Forcing LINQ to use a Stored Procedure when accessing a Database访问数据库时强制 LINQ 使用存储过程
【发布时间】:2010-11-22 22:32:14
【问题描述】:

我已经进行了一些搜索(通过网络和 SO),但到目前为止一直无法找到直接回答这个问题的内容:

是否有强制 L2S 在访问数据库时使用存储过程?

这与简单地将 SPROC 与 L2S 一起使用不同:问题是,我依靠 LINQ 来延迟加载元素,方法是通过生成的“子属性”进行访问。如果我使用 SPROC 检索一个表的元素,然后映射到 LINQ 中的实体,然后访问子属性,我相信 LINQ 将使用动态 sql 从数据库中检索寄存器,这违背了我的目的。


更新:

对不起,如果上面的文字不清楚。我真正想要的是类似于更新、插入和删除的“默认方法”,但是,选择。我希望每次访问都通过 SPROC 完成,但我想使用 Child Property

只是为了让您不要认为我疯了,问题是我的 DAL 是使用子属性构建的,并且我正在使用动态 SQL 通过 L2S 访问数据库,但上周客户告诉我所有数据库访问必须通过 SPROCS 完成。

【问题讨论】:

    标签: linq-to-sql stored-procedures


    【解决方案1】:

    我不相信有开箱即用的开关或设置,并且会自动映射到您所描述的方式使用 t sprocs。但是现在你不能改变生成的 DBML 文件来做你想做的事是有原因的。如果我有两个相关的表,一个 Catalog 表和 CatalogItem 表,Linq2SQL 生成器自然会给我一个 CatalogItems on Catalog 的属性,代码如下:

    private EntitySet<shelf_myndr_Previews_CatalogItem> _shelf_myndr_Previews_CatalogItems;
    
    [global::System.Data.Linq.Mapping.AssociationAttribute(Name="CatalogItem", Storage="_CatalogItems", ThisKey="Id", OtherKey="CatalogId")]
    public EntitySet<CatalogItem> CatalogItems
        {
            get
            {
                return this._CatalogItems;
                                //replace this line with a sproc call that ultimately
                                //returns the expected type
            }
            set
            {
                this._CatalogItems.Assign(value);
                                //replace this line with a sproc call that ultimately
                                //does a save operation
            }
        }
    

    没有什么能阻止您将代码更改为那里的 sproc 调用。对于更大的应用程序来说,这将是一些努力,我相信您会从中获得您认为会得到的好处。

    【讨论】:

    • +1 因为这可能是唯一的方法,但它并不漂亮。这是生成的代码,因此您必须小心不要用 DBML 的重新生成覆盖它。
    • 不,不漂亮,但 DBML 被设计为以这种方式编辑。也许不是这个目的。是的,必须小心再生,但它是你有源代码控制的,对吧?
    • 系统小;如果我必须在 DAL 级别进行重构,那么重构会更糟,所以我想这是最好的方法。谢谢,我去看看。
    • 我试过这样做,但有一个问题,我无法访问 DataContext,没有它我无法调用 SPROC。有什么想法吗?
    • 一分钱,一磅。如果您已经在更改 Linq2SQL 对象的行为以支持返回 sproc 结果,为什么不更改构造函数以将 DataContext 作为参数呢?虽然在这一点上,对你的项目一无所知,但我认为你可能正在危险地接近为自己挖一个大洞。您是否考虑过其他想法,例如存储库模式?您可以构建您的业务对象/实体/关系,并且在内部您可以使用 L2SQL 并确保您只调用 sprocs。我会担心维护的噩梦。
    【解决方案2】:

    如何在父实体中使用部分 OnLoaded() 方法加载子实体?这将使您避免弄乱生成的代码。当然,它不再是延迟加载,而是一种简单的方法。

    例如:

    public partial class Supplier
    {
        public List<Product> Products { get; set; }
    
        partial void OnLoaded()
        {
            // GetProductsBySupplierId is the SP dragged into your dbml designer
            Products = dataContext.GetProductsBySupplierId(this.Id).ToList();
        }
    }
    

    【讨论】:

    • 我将您的想法与 Jonathan 的想法混合在一起,将自定义属性创建为部分类,但是如何访问 dataContext(就像您在上面所做的那样)?我好像无权访问它。
    • 不同的系统以不同的方式提供对当前上下文的访问。您必须决定如何在您的设计中进行(这有助于在设计过程的早期进行,所以我建议您尽快弄清楚)。在不知道您正在开发什么类型的应用程序以及您现有的 DAL 是什么的情况下(听起来您有一些限制),恐怕除了提供一些资源之外我无能为力。 Rick Strahl 的文章不错:west-wind.com/weblog/posts/246222.aspx 并参见 NerdDinner 的 Pt 3 了解存储库模式:nerddinnerbook.s3.amazonaws.com/Intro.htm
    【解决方案3】:

    以这种方式调用您的存储过程:

    GetProductsByCategoryName 是存储过程的名称。

    http://weblogs.asp.net/scottgu/archive/2007/08/16/linq-to-sql-part-6-retrieving-data-using-stored-procedures.aspx

    【讨论】:

    • 哈维,感谢您的回复。我的问题是,假设您的Product 实体有一个名为“SupplierId”的列,它是一个名为“Suppliers”的表的 FK,该表映射到一个名为 Supplier 的实体和一个名为“Supplier”的Child Property。使用本机 LINQ,我只需转到 product.Supplier.Name 即可检索相关供应商的名称。但是,我希望通过使用 SPROC 来访问供应商表。有可能吗?
    猜你喜欢
    • 1970-01-01
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-31
    • 2013-04-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多