如何在LINQ到DB模型类中的表之间添加关系

时间:2015-03-18 11:32:07

标签: c# linq2db

我正在使用LINQ to DB(linq2db),我有一个类,Activity.cs,它有一个Customer属性,如下所示:

public Customer Customer { get; set; }

客户类:

    public class Customer
{
    [PrimaryKey, Identity]
    [Column(Name = "CustomerId"), NotNull]
    public string Id { get; set; }

    [Column(Name = "Name")]
    public string Name { get; set; }
}

现在,我希望能够做到这样的事情:

db.Activities.First().Customer.Name  //Returns the customer name of an activity

如何设置实体之间的关系,以便我可以按照上面的说明进行操作?

(是的,我知道将Id字段作为字符串是没有意义的,我必须对付凌乱的旧版Access数据库)

2 个答案:

答案 0 :(得分:1)

如果我理解,一个Activity只有一个Customer。如果是这样,您应该在Activity班级添加关系:

[Table( Name = "Customers" )]
public class Customer
{
    [PrimaryKey, Identity]
    [Column(Name = "CustomerId"), NotNull]
    public string Id { get; set; }

    [Column(Name = "Name")]
    public string Name { get; set; }
}

[Table( Name = "Activities" )]
public class Activity
{
    [PrimaryKey, Identity]
    [Column(Name = "ActivityId"), NotNull]
    public string Id { get; set; }

    [Column( Name = "Customer" )] 
    private int? customerId; 

    private EntityRef<Customer> _customer = new EntityRef<Customer>( );

    [Association(IsForeignKey = true, Storage = "_customer", ThisKey = "customerId" )]
    public Customer Customer{
        get { return _customer.Entity; }
        set { _customer.Entity = value; }
    }
}

A good article about this subject

编辑:

当协会不起作用时的走动:

[Table( Name = "Activities" )]
public class Activity
{
    [PrimaryKey, Identity]
    [Column(Name = "ActivityId"), NotNull]
    public string Id { get; set; }

    [Column( Name = "CustomerId" )] 
    public int? CustomerId; 

}

您可以从以下活动中检索客户:

var activity = db.Activities.FirstOrDefault()
var customer = db.Customers.FirstOrDefault(c => c.Id = activity.CustomerId);

答案 1 :(得分:1)

这个问题是关于Linq2db的使用,而不是LinqToSQL的使用。 Linq2db是一种替代ORM,而不是支持其他数据库类型,如Postgresql或SQLite。 Linq2db针对不消耗许多资源进行了优化,因此尝试直接访问db.Activities.First().Customer.Name,总是会抛出异常,因为它不会加载Costomer的值。

例如,如果我们使用以下代码来查询Northwind数据库的Customers,那么

using (var db = new NorthwindDB())
        {
            var q = from c in db.Customers
                    select c;
        }

它将生成如下的SQL查询:

{-- NorthwindDB SqlServer.2008
SELECT
    [t1].[CustomerID],
    [t1].[CompanyName],
    [t1].[ContactName],
    [t1].[ContactTitle],
    [t1].[Address],
    [t1].[City],
    [t1].[Region],
    [t1].[PostalCode],
    [t1].[Country],
    [t1].[Phone],
    [t1].[Fax]
FROM
    [dbo].[Customers] [t1]
}

虽然Customer实体与Order实体具有一对多的关系,但它们不会加载这些值。对于我们想要获得客户订单的情况,我建议使用未知类型(或简单类)作为以下查询。

using (var db = new NorthwindDB())
        {
            var q = from c in db.Customers
                    select new
                    {
                        c.CompanyName,
                        EmployeeName = c.Orders.First().Employee.FirstName
                    };
        }

它将生成如下的SQL查询:

{-- NorthwindDB SqlServer.2008
SELECT
    [t4].[CompanyName],
    [t3].[FirstName] as [FirstName1],
    [t3].[c1] as [c11]
FROM
    [dbo].[Customers] [t4]
        OUTER APPLY (
            SELECT TOP (1)
                [t1].[FirstName],
                1 as [c1]
            FROM
                [dbo].[Orders] [t2]
                    LEFT JOIN [dbo].[Employees] [t1] ON [t2].[EmployeeID] = [t1].[EmployeeID]
            WHERE
                [t4].[CustomerID] = [t2].[CustomerID]
        ) [t3]
}