2

我正在使用 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 数据库)

4

2 回答 2

2

如果我很好理解,一个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; }
    }
}

关于这个主题的一篇好文章

编辑:

关联不起作用时的走动:

[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);
于 2015-03-18T12:04:55.007 回答
1

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

例如,如果我们使用以下代码查询罗斯文数据库的客户,

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]
}
于 2015-10-12T19:26:09.467 回答