【问题标题】:How the Application layer will be able to dynamicly query the DB in the DAL layer?应用层如何能够动态查询 DATA 层中的数据库?
【发布时间】:2013-03-21 07:58:58
【问题描述】:

C#、LINQ to SQL

一些建议我打开新主题而不是那个主题,因为我的问题没有解决方案。现在我需要你的帮助来重新设计我的图层。 Linq To Sql - Making a dynamic search for the Application layer without exposing DAL layer as DLL


我的项目由 3 层组成:DAL、BL、应用程序。 Linq2Sql 存在于 DAL 层中,它为数据库中的每个表自动生成一个类,以及一个 ContextObject 来管理数据库。我无法更改此类中的任何内容,因为数据库中的任何更改都会导致重新自动生成这些类。

[global::System.Data.Linq.Mapping.DatabaseAttribute(Name="ClientDB")]
public partial class LinqClientDBDataContext : System.Data.Linq.DataContext

[global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.Clients")]
public partial class Client : INotifyPropertyChanging, INotifyPropertyChanged

这些类暴露给 BL 层。 Application 层不需要暴露给 LinqClientDBDataContext (ContextObject),因此我不能将 Application 层暴露给 Linq2Sql 的任何自动生成的代码(在本例中为 Client 类)。这就是为什么我制作了一个由 DAL.Client 对象在 BL 层生成的“重复”客户端类:

private BusinessLogic.Client Convert(ClientDataAccessLayer.Client Client)
        {
            return new BusinessLogic.Client(Client.ClientID,..);
        }

当我尝试给应用层一个 IQueryable 时,问题就来了,这样应用层就可以动态地创建查询并根据需要过滤结果:

public IQueryable<BusinessLogic.Client> Clients()
        {
            this.MainDB.Clients.Select<ClientDataAccessLayer.Client, BusinessLogic.Client>((ClientDAL1) => Convert(ClientDAL1));
        }
ClientLogic().Clients().Where((ClientBL1)=>ClientBL1.ClientID==4);

异常:方法“BusinessLogic.Client Convert(ClientDataAccessLayer.Client)”不支持对 SQL 的转换。

这段代码给出了这个异常,我知道为什么,但我找不到任何更好的解决方案。

请随时帮助我重新设计我的项目,以便应用程序可以动态查询数据库。

非常感谢,斯塔夫·阿尔菲。

【问题讨论】:

    标签: c# linq-to-sql data-access-layer business-logic application-layer


    【解决方案1】:

    您不能在 linq-to-sql 查询中调用构造函数。你必须像这样写你的转换器

    // NOTE: this is an expression, not a method
    private static Expression<Func<ClientDataAccessLayer.Client, BusinessLogic.Client>> Convert =
        x => new BusinessLogic.Client // NOTE: initializer, not a constructor
        {
            Id = x.Id,
            ...
        };
    
    public IQueryable<BusinessLogic.Client> Clients()
    {
        this.MainDB.Clients.Select(Convert);
    }
    

    假设您的查询中没有其他部分正在调用任意的、非 Linq-to-SQL 兼容的函数,该错误应该会消失。

    【讨论】:

    • 这非常有效!但是初始化器和构造器之间的区别是什么?这个解决方案仍然迫使我为 BusinessLogic.Client 创建一个非参数构造函数。
    • @StavAlfi 初始化器是一个表达式。构造函数是一个方法调用。 Linq-to-SQL 查询提供程序只能检查表达式。
    • @StavAlfi 很高兴我能帮上忙
    猜你喜欢
    • 2021-03-08
    • 2023-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-29
    • 1970-01-01
    • 1970-01-01
    • 2011-11-30
    相关资源
    最近更新 更多