Application层如何能够动态查询DAL层中的DB?

时间:2013-03-30 20:33:59

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

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层中是exsist,他为数据库中的每个表自动生成一个类,并使用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层生成的“Duplicate”类Client:

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

当我尝试为Application层提供IQueryable时,问题就出现了,因此Application层可以动态创建查询并根据需要过滤结果:

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转换(ClientDataAccessLayer.Client)'没有受支持的SQL转换。

这段代码给出了这个例外,我知道为什么但是我找不到更好的解决方案来解决这个问题。

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

非常感谢,Stav Alfi。

1 个答案:

答案 0 :(得分: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兼容的函数,错误应该消失。