C# 实体框架代码首先,获取外键值的访问权限

C# 实体框架代码首先,获取外键值的访问权限,c#,sql,entity-framework,C#,Sql,Entity Framework,假设我们有一个具有以下实体的项目: class User { public Guid Id { get; set; } public List<Message> Messages { get; set; } ... } class Message { public Guid Id { get; set; } public string Message { get; set; } } 现在考虑一个SeaNeo,在这里我想得到所有用户发布的所有

假设我们有一个具有以下实体的项目:

class User
{
    public Guid Id { get; set; }
    public List<Message> Messages { get; set; }
    ...
}

class Message
{
    public Guid Id { get; set; }
    public string Message { get; set; }
}

现在考虑一个SeaNeo,在这里我想得到所有用户发布的所有消息,如何在不拉用户信息的情况下实现这一点呢?不使用context.Users.Include?


我知道实体框架在消息表中创建了一个列,该列保存发布此消息的用户的Id,但是我如何能够访问此值?因为它不是我的原始类中的属性。

您可以将导航属性添加到Message类中:

然后像这样查询您的上下文:

var userMessages = context.Messages
    .Where(m => m.User.Id == 5);
SELECT [Extent1].[Column1],
       [Extent1].[Column2],
       [Extent1].[Column3]
FROM [dbo].[Messages] AS [Extent1] 
WHERE 5 = [Extent1].[UserId]
这是更整洁的方法。或者,您可以从用户开始,但这有点尴尬:

var userMessages = context.Users
    .Where(u => u.Id == 5)
    .SelectMany(u => u.Messages);
这两种方法最终将生成类似的SQL,如下所示:

var userMessages = context.Messages
    .Where(m => m.User.Id == 5);
SELECT [Extent1].[Column1],
       [Extent1].[Column2],
       [Extent1].[Column3]
FROM [dbo].[Messages] AS [Extent1] 
WHERE 5 = [Extent1].[UserId]

您可以将导航属性添加到消息类中:

然后像这样查询您的上下文:

var userMessages = context.Messages
    .Where(m => m.User.Id == 5);
SELECT [Extent1].[Column1],
       [Extent1].[Column2],
       [Extent1].[Column3]
FROM [dbo].[Messages] AS [Extent1] 
WHERE 5 = [Extent1].[UserId]
这是更整洁的方法。或者,您可以从用户开始,但这有点尴尬:

var userMessages = context.Users
    .Where(u => u.Id == 5)
    .SelectMany(u => u.Messages);
这两种方法最终将生成类似的SQL,如下所示:

var userMessages = context.Messages
    .Where(m => m.User.Id == 5);
SELECT [Extent1].[Column1],
       [Extent1].[Column2],
       [Extent1].[Column3]
FROM [dbo].[Messages] AS [Extent1] 
WHERE 5 = [Extent1].[UserId]

可以明确定义FK,这样就不必解析用户对象

class Message
{
    public Guid Id { get; set; }
    public string Message { get; set; }

    public int UserID { get; set; }
    [ForeignKey("UserID")]
    public virtual User User { get; set; }
}

然后在需要时对用户进行操作,但如果您只想按用户ID拉取或更改用户ID,则可以这样做。

您可以明确定义FK,这样就不必解析用户对象

class Message
{
    public Guid Id { get; set; }
    public string Message { get; set; }

    public int UserID { get; set; }
    [ForeignKey("UserID")]
    public virtual User User { get; set; }
}

然后在需要时对用户进行操作,但如果您只想通过用户ID或更改用户ID,则可以这样做。

嘿,Yushatak!使用ForeignKey注释与不使用它但保持虚拟状态(如DavidG posted)之间的区别是什么?如果使用注释,您将创建一个可访问的密钥属性(在本例中为UserID),您可以读取/写入/操作该属性。如果您不使用注释,这将发生在幕后,并且无法通过EF进行操作。显然,手动FK是不必要的,因为表达式解析为使用EF per DavidG中的ID属性。嘿,Yushatak!使用ForeignKey注释与不使用它但保持虚拟状态(如DavidG posted)之间的区别是什么?如果使用注释,您将创建一个可访问的密钥属性(在本例中为UserID),您可以读取/写入/操作该属性。如果不使用注释,这将发生在幕后,并且无法通过EF进行操作。显然,手动FK不是必需的,因为表达式解析为在EF per DavidG中使用ID属性。嘿,DavidG!使用ForeignKey注释和不使用它之间有什么区别?实际上没有区别,如果您希望明确,那么可以随意添加它。实际上,您不需要该属性,因为根据惯例,实体框架将用户导航属性映射到名为UserId的Id字段。这会在两个实体之间创建任何连接吗?删除其中一个会导致删除另一个吗?如果它们之间已经有连接,EF约定将创建外键。在声明WillCascadeOnDelete之前,不会实际创建外键约束。如果我没有弄错的话,FK注释将仅由EF来告诉要使用哪个连接属性并在列上创建索引!使用ForeignKey注释和不使用它之间有什么区别?实际上没有区别,如果您希望明确,那么可以随意添加它。实际上,您不需要该属性,因为根据惯例,实体框架将用户导航属性映射到名为UserId的Id字段。这会在两个实体之间创建任何连接吗?删除其中一个会导致删除另一个吗?如果它们之间已经有连接,EF约定将创建外键。在声明WillCascadeOnDelete之前,不会实际创建外键约束。如果我没有弄错的话,FK注释将仅由EF来告诉要使用哪个join属性并在列上创建索引