首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用Linq和Entity连接两个可连接性?

如何使用Linq和Entity连接两个可连接性?
EN

Stack Overflow用户
提问于 2011-11-04 23:10:58
回答 2查看 1.9K关注 0票数 2

我有一个非常规范化的数据库,我试图将两个连接表连接在一起。

我的目标是只显示用户有权限的文档。我正在使用实体框架,并为下面的表设置了几个外键:

关系(外键)

代码语言:javascript
运行
复制
Users  --------------------------------------------- 
                                                    |
                          UserGroupMembership    (UserID, GroupID)
                                                              |  
                                                              |
Groups ----- -------------------------------------------------|
    |
    |
    |---------------------------------------------------------|
                                                              | 
                                                              | 
XDocuments               XDocumentSecurity   (DocumentID, GroupID)
       |                                           |
       ---------------------------------------------

表定义

代码语言:javascript
运行
复制
public partial class Users : EntityObject  
{
    public int UserID {get;set;} //PK
    public string UserDisplayName {get;set;}  
    public DateTime CreateDate {get;set;} 
    public DateTime LoginDate {get;set;}  
} 

public partial class Groups : EntityObject  
{
    public int GroupID {get;set;} //PK
    public string GroupDisplayName {get;set;}  
    public DateTime CreateDate {get;set;} 
    public DateTime LoginDate {get;set;}  
} 


public partial class UserGroupMembership: EntityObject  // JoinTable
{
   public int UserID {get;set;} //PK
   public int GroupID {get;set;} //PK

   // Not sure if this extra columns below causes an issue
   public bool CanView {get;set;}
   public bool CanDelete {get;set;} 
   public bool CanUpdate {get;set;} 
   public DateTime CreateDate {get;set;}   
}

public partial class XDocumentSecurity : EntityObject // JoinTable
{
    public int DocumentID {get;set;} //FK
    public int GroupID {get;set;} //FK

     public DateTime CreateDate {get;set;}   // Not sure if this extra column causes an issue  
 } 

public partial class XDocuments : EntityObject  
{
    public int DocumentID {get;set;} //PK
    public string URL {get;set;}  
    public DateTime CreateDate {get;set;} 
} 

我听说过许多关于Linq to EF如何以一种性能不太理想的方式更改SQL查询的故事。

下面是操作者样本,它似乎最适用于我正在做的事情。我只需获取当前用户所属的组的列表,并发布此查询的修改版本:

代码语言:javascript
运行
复制
public void Linq50() 
{ 
    int[] numbersA = { 0, 2, 4, 5, 6, 8, 9 }; 
    int[] numbersB = { 1, 3, 5, 7, 8 }; 

    var commonNumbers = numbersA.Intersect(numbersB); 

    Console.WriteLine("Common numbers shared by both arrays:"); 
    foreach (var n in commonNumbers) 
    { 
        Console.WriteLine(n); 
    } 
}

问题

  • 如何查看EF生成的SQL查询?
  • 有什么更好的方法来解决这个问题(如果有的话)
EN

回答 2

Stack Overflow用户

发布于 2011-11-04 23:31:16

如果您对所有键和外键具有导航属性,则没有Intersect的替代查询如下:

代码语言:javascript
运行
复制
var query = context.XDocuments
    .Where(d => d.Groups.Any(g => g.Users.Any(u => u.UserID == givenUserId)));

(“筛选至少一个具有键=givenUserId的用户的组中的所有文档”)

我不知道这是否会更好的表现。

在EF 4.1中,您可以简单地通过以下方法检查生成的SQL:

代码语言:javascript
运行
复制
var sql = query.ToString();

编辑

我对您的模型的理解如下:

有相应表格的三个实体:

代码语言:javascript
运行
复制
public class User
{
    public int UserID { get; set; }
    public ICollection<Group> Groups { get; set; }
}

public class Group
{
    public int GroupID { get; set; }
    public ICollection<User> Users { get; set; }
    public ICollection<XDocument> Documents { get; set; }
}

public class XDocument
{
    public int DocumentID { get; set; }
    public ICollection<Group> Groups { get; set; }
}

UserGroup之间还有GroupXDocument之间的多对多关系:

代码语言:javascript
运行
复制
modelBuilder.Entity<User>()
    .HasMany(u => u.Groups)
    .WithMany(g => g.Users)
    .Map(c =>
    {
        c.MapLeftKey("UserID");
        c.MapRightKey("GroupID");
        c.ToTable("UserGroupMembership");  // join table name, no entity
    });

modelBuilder.Entity<XDocument>()
    .HasMany(d => d.Groups)
    .WithMany(g => g.Documents)
    .Map(c =>
    {
        c.MapLeftKey("DocumentID");
        c.MapRightKey("GroupID");
        c.ToTable("XDocumentSecurity");  // join table name, no entity
    });

在此模型和映射中,上述查询应该是可能的。不需要直接访问连接表(实际上不能通过LINQ实体访问它们,EF在内部管理这些表)。

票数 3
EN

Stack Overflow用户

发布于 2011-11-04 23:35:06

您还可以使用以下两种方法查看EF 4.1生成的SQL

  • SQL事件探查器
  • LINQPad

尽管此时,您需要为EF4.1使用LINQPadβ

关于你的第二个问题,我相信你的问题会翻译得很好。使用LINQPad检查SQL,以下查询

代码语言:javascript
运行
复制
var a1 = Addresses.Where(a => a.City.ToUpper().EndsWith("L")).Select(a => a.AddressID);
var a2 = Addresses.Where(a => a.City.ToUpper().StartsWith("B")).Select(a => a.AddressID);

var x1 = a1.Intersect(a2);

翻译成

代码语言:javascript
运行
复制
SELECT 
[Intersect1].[AddressID] AS [C1]
FROM  (SELECT 
    [Extent1].[AddressID] AS [AddressID]
    FROM [Person].[Address] AS [Extent1]
    WHERE UPPER([Extent1].[City]) LIKE N'%L'
INTERSECT
    SELECT 
    [Extent2].[AddressID] AS [AddressID]
    FROM [Person].[Address] AS [Extent2]
    WHERE UPPER([Extent2].[City]) LIKE N'B%') AS [Intersect1]

如果您的模型支持的话,我认为@Slauma建议使用导航特性是可行的。

不过,去找LINQPad --你不会后悔的:)

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8016773

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档