1

我正在开发一个 3 层应用程序。我也使用 LINQ to SQL 进行数据访问。

DataLayer 有一个返回客户表的函数:

public Table<Customer> getCustomers()
{
    DataContext context = new DataContext();
    Table<Customer> customerTable = context.GetTable<Customer>();

    return customerTable;
}

它被提供给业务层,其中结果被传递给表示层IEnumerable<Customer>

public IEnumerable<Customer> getCustomers()
{
    CustomerDAL customerDAL = new CustomerDAL();

    return from c in customerDAL.getCustomers() select c;            
}

在表示层中,我只是将 IEnumerable 用于 DatagridView 的数据源。

如果我有另一个表格,如“信息”和相应的customerDAL.getInfo()表格怎么办?现在我想在业务层的方法中进行连接查询。我想象它是这样的:

public IEnumerable<Customer> getCustomerInfo()
{
    CustomerDAL customerDAL = new CustomerDAL ();

    return from c in customerDAL.getCustomers()
                  join i in customerDAL.getInfo() on c.id equals i.InfoID
                  select new { c.id, c.Name, i.DateTime, i.Project };
}

问题是 IEnumerable 需要对象的类型。我的返回值不再是客户表,而是客户表和信息表的组合。我做对了吗?这里返回值的正确选择是什么?

根据您的建议,我创建了一个自定义类CustomerInfo.cs

public class CustomerInfo
    {        
        string name { get; set; }
        long id { get; set; }
        string dateTime { get; set; }
        string project { get; set; }


        public CustomerInfo(long _id, string _name, string _date, string _project) 
        {
            name = _name;
            id = _id;
            dateTime = _date;
            project = _project;
        }
    }

然后我调用与 Reed 描述的完全相同的方法。但是在表示层中,当我设置数据源时,我得到了异常:

The query contains references to items defined on a different data context.

实际上,并非所有实体类都在同一个 .dbml 文件中。有什么问题?

4

4 回答 4

1

这里返回值的正确选择是什么?

如果要返回强类型类,则需要一个自定义类来表示这种类型,例如CustomerInfo类。您需要定义此类,并包含适当的属性和构造函数。然后你可以这样做:

public IEnumerable<CustomerInfo> GetCustomerInfo()
{
        CustomerDAL customerDAL = new CustomerDAL();

        return from c in customerDAL.getCustomers()
                    join i in customerDAL.getInfo() on c.id equals i.InfoID
                    select new CustomerInfo(c.id, c.Name, i.DateTime, i.Project);
}

这将允许您以强类型的方式返回所需的确切信息。我认为在这种情况下创建自定义类尤其重要,因为您已将其定义为公共 API 的一部分。

于 2012-08-27T20:54:23.897 回答
1

关于第二个错误:

然后我调用与 Reed 描述的完全相同的方法。但是在表示层中,当我设置 DataSource 时出现异常:查询包含对在不同数据上下文中定义的项目的引用。

Most likely your DAL is instantiating a separate instance of the context for each table that you are returning (Typical in a ActiveRecord patterned implementation). In order for the join to work, both tables need to be retrieved by the same context object. You may want to modify your DAL so that you inject the context in the constructor of the DALs so that you can centralize the lifetime of the context.

于 2012-08-28T17:31:25.447 回答
0

到目前为止,一切看起来都不错。如果您只想在单个方法的范围内使用查询,那么使用匿名类(这是您当前正在做的)就可以了。既然你不是,你需要为你的投影创建一个具体的类,以便你可以返回它。

查询将变为:

select new SomeClassYouAreAboutToCreate { c.id, c.Name, i.DateTime, i.Project };

该类可能只有一堆属性,id,Name等。您只需将这些属性设置在Select.

于 2012-08-27T20:50:32.137 回答
0

当你创建一个这样的匿名对象时,它的类型是dynamic. 因此,要返回这样的匿名对象列表,您将使用以下签名:

public IEnumerable<dynamic> getCustomerInfo() {
    CustomerDAL customerDAL = new CustomerDAL ();

    return from c in customerDAL.getCustomers()
        join i in customerDAL.getInfo() on c.id equals i.InfoID
        select new { c.id, c.Name, i.DateTime, i.Project };
}

但请记住,该dynamic类型有其缺点。特别是,您失去了强类型,这可能会引入难以发现的错误。您应该考虑Servy 的答案以获得更强大的解决方案。

于 2012-08-27T20:55:33.677 回答