C# 如何查询复杂的n:m关系以获取C中的IEnumerable#

C# 如何查询复杂的n:m关系以获取C中的IEnumerable#,c#,asp.net,linq-to-sql,C#,Asp.net,Linq To Sql,在我的sql数据库中,我有一个多对多(n:m)关系,如下所示: 对于我的asp.net web应用程序(使用EF和数据库优先方法),我需要提取所有组的表质量记录(使用C#和linq),这些组是给定组所属的同一关联s中的成员 下面我给出了示例数据,以演示G_Id=1的给定组所需的查询结果 从样本数据中,我们可以看到给定的组是关联a_Id=1和a_Id=2的成员。因此,我们需要看看哪些其他群体是这些协会的成员。在给定的数据中,我们看到,G_Id=2的组也是关联a_Id=1的成员,G_Id=3的组

在我的sql数据库中,我有一个多对多(n:m)关系,如下所示:

对于我的asp.net web应用程序(使用EF和数据库优先方法),我需要提取所有组的表质量记录(使用C#和linq),这些组是给定组所属的同一关联s中的成员

下面我给出了示例数据,以演示G_Id=1的给定组所需的查询结果

从样本数据中,我们可以看到给定的组是关联a_Id=1和a_Id=2的成员。因此,我们需要看看哪些其他群体是这些协会的成员。在给定的数据中,我们看到,G_Id=2的组也是关联a_Id=1的成员,G_Id=3的组也是关联a_Id=2的成员。 因此,我们必须从表Quality中收集所有记录,其中G_Id=1、G_Id=2和G_Id=3,查询结果为:

我能够编写一个有效的C#IEnumerable controller操作(见下文)来获取一个组的所有质量记录,但未能提出一个也能解释相关组记录的查询

public IEnumerable<Quality> Get()
{
    int g_Id = myAppPrincipal.G_Id;
    var group = UnitOfWork.GetById<Group>(g_Id);
    var groupQualities = group.Qualities;
    // Qualities is a public virtual ICollection of Quality inside the class Group

    IList<Quality> result = groupQualities.Select(entity => new Quality()
    {
        Q_Id = entity.Q_Id,
        Description = entity.Description,
        ...
    }).ToList();

    return result;
}
public IEnumerable Get()
{
int g_Id=myAppPrincipal.g_Id;
var group=UnitOfWork.GetById(g_Id);
var groupQualities=组质量;
//Qualities是班级组内质量的公共虚拟集合
IList result=groupquality.Select(实体=>newquality()
{
Q_Id=entity.Q_Id,
描述=实体。描述,
...
}).ToList();
返回结果;
}
如果有人能帮我建立正确的查询,我将不胜感激

见以下班级结构:

public class Entity
{
    /// <summary>
    /// Unique identifier
    /// </summary>
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public virtual int Id
    {
        get;
        set;
    }

    /// <summary>
    /// Concurrency check property
    /// </summary>
    [Timestamp]
    public virtual byte[] Version
    {
        get;
        set;
    }

    /// <summary>
    /// Determines whether entity is new
    /// </summary>
    [Bindable(false)]
    [ScaffoldColumn(false)]
    public virtual bool IsNew
    {
        get
        {
            return Id == 0;
        }
    }

    public override string ToString()
    {
        return this.DumpToString();
    }
}

public class Association: Entity
{
    public string Description { get; set; }
}

public class Assoc_Group: Entity
{
    public int A_ID { get; set; }
    public int G_ID { get; set; }

    [IgnoreDataMember]
    public override byte[] Version
    {
        get;
        set;
    }
}

public class Group: Entity
{
    public Group()
    {
        Qualities = new List<Quality>();
    }

    public string Description { get; set; }

    public virtual ICollection<Quality> Qualities { get; set; }

}

public class Quality: Entity
{
    public int? G_ID { get; set; }
    public string Description { get; set; }

    public virtual Group Group { get; set; }

    [IgnoreDataMember]
    public override byte[] Version
    {
        get;
        set;
    }
}
公共类实体
{
/// 
///唯一标识符
/// 
[数据库生成(DatabaseGeneratedOption.Identity)]
公共虚拟整数Id
{
得到;
设置
}
/// 
///并发检查属性
/// 
[时间戳]
公共虚拟字节[]版本
{
得到;
设置
}
/// 
///确定实体是否为新实体
/// 
[可装订(假)]
[脚手架立柱(假)]
公共虚拟图书馆是新的
{
得到
{
返回Id==0;
}
}
公共重写字符串ToString()
{
返回此.DumpToString();
}
}
公共类协会:实体
{
公共字符串说明{get;set;}
}
公共类关联组:实体
{
公共int A_ID{get;set;}
公共int G_ID{get;set;}
[IgnoreDataMember]
公共覆盖字节[]版本
{
得到;
设置
}
}
公共类组:实体
{
公共组()
{
质量=新列表();
}
公共字符串说明{get;set;}
公共虚拟ICollection属性{get;set;}
}
公共类质量:实体
{
公共int?G_ID{get;set;}
公共字符串说明{get;set;}
公共虚拟组{get;set;}
[IgnoreDataMember]
公共覆盖字节[]版本
{
得到;
设置
}
}
和相应的映射:

public class AssociationMap : EntityTypeConfiguration<Association>
{
    public AssociationMap()
    {
        // Primary Key
        HasKey(t => t.Id);

        // Properties
        Property(t => t.Description)
            .IsRequired();

        // Table & Column Mappings
        ToTable("Association");
        Property(t => t.Id).HasColumnName("A_ID");
        Property(t => t.Description).HasColumnName("Description");

        Ignore(t => t.Version);
    }
}

class Assoc_GroupMap : EntityTypeConfiguration<Assoc_Group>
{
    public Assoc_GroupMap()
    {

        ToTable("Assoc_Group");
        Property(t => t.Id).HasColumnName("AG_ID");
        Property(t => t.A_ID).HasColumnName("A_ID");
        Property(t => t.G_ID).HasColumnName("G_ID");

        Ignore(property => property.Version);
    }
}

public class GroupMap : EntityTypeConfiguration<Group>
{
    public GroupMap()
    {
        // Primary Key
        HasKey(t => t.Id);

        // Table & Column Mappings
        ToTable("Group");
        Property(t => t.Id).HasColumnName("G_ID");


        Ignore(t => t.Version);
    }
}


public class QualityMap : EntityTypeConfiguration<Quality>
{
    public QualityMap()
    {
        // Primary Key
        HasKey(t => t.Id);

        // Table & Column Mappings
        ToTable("Quality");
        Property(t => t.Id).HasColumnName("Q_ID");
        Property(t => t.G_ID).HasColumnName("G_ID");
        ...

        // Relationships
        HasOptional(t => t.Group)
            .WithMany(t => t.Qualities)
            .HasForeignKey(d => d.G_ID);
    }
}
公共类AssociationMap:EntityTypeConfiguration
{
公共协会地图()
{
//主键
HasKey(t=>t.Id);
//性质
属性(t=>t.Description)
.IsRequired();
//表和列映射
可转让(“关联”);
属性(t=>t.Id);
属性(t=>t.Description).HasColumnName(“Description”);
忽略(t=>t.Version);
}
}
类Assoc_GroupMap:EntityTypeConfiguration
{
公共协会组图()
{
ToTable(“Assoc_集团”);
属性(t=>t.Id);
属性(t=>t.A_ID).HasColumnName(“A_ID”);
属性(t=>t.G_ID);
忽略(property=>property.Version);
}
}
公共类GroupMap:EntityTypeConfiguration
{
公共组映射()
{
//主键
HasKey(t=>t.Id);
//表和列映射
ToTable(“集团”);
属性(t=>t.Id);
忽略(t=>t.Version);
}
}
公共类QualityMap:EntityTypeConfiguration
{
公共质量地图()
{
//主键
HasKey(t=>t.Id);
//表和列映射
易变(“质量”);
属性(t=>t.Id);
属性(t=>t.G_ID);
...
//关系
has可选(t=>t.Group)
.有许多(t=>t.品质)
.HasForeignKey(d=>d.G_ID);
}
}

据我所知,您需要一些特定组的所有父关联中的所有组质量,因此:

public IEnumerable<Quality> Get()
{
    int g_Id = myAppPrincipal.G_Id;
    var group = UnitOfWork.GetById<Group>(g_Id);
    var associatedGroups = group.Assoc_Group.Groups;
    var qualities = new List<Quality>();
    foreach (var assoc in associatedGroups.Select(t => t.Association).Distinct())
    {
        qualities.AddRange(assoc.Assoc_Groups.SelectMany(t => t.group.Qualities).ToList());
    }

    var result = qualities.Distinct();
    return result;
}
public IEnumerable Get()
{
int g_Id=myAppPrincipal.g_Id;
var group=UnitOfWork.GetById(g_Id);
var associatedGroups=group.Assoc\u group.Groups;
var qualities=新列表();
foreach(associatedGroups.Select(t=>t.Association.Distinct())中的var assoc)
{
AddRange(assoc.assoc_Groups.SelectMany(t=>t.group.qualities.ToList());
}
var result=qualities.Distinct();
返回结果;
}

在上述情况下,我希望GetById也能获取相关实体,如果没有,那么您必须更改为GetById方法以包含相关实体。否则,您可以通过单独调用来单独获取关联的查询。

您可以使用如下嵌套查询:

DECLARE @GivenGroup AS Int = 1

SELECT DISTINCT Q_Id
FROM Quality q
WHERE q.G_Id IN
(
    SELECT DISTINCT G_Id
    FROM Assoc_Group ag
    WHERE ag.A_Id IN
    (
        SELECT a.A_Id
        FROM Association a
        INNER JOIN Assoc_Group ag ON a.A_Id = ag.A_Id
        WHERE ag.G_Id = @GivenGroup
    )
)
至少对于SQL Server

您可以在这里尝试:

要使用C#查询SQL数据库,可以使用SqlClient

var SQL = new StringBuilder();
// Build SQL here. use SQL.AppendLine("SELECT ...")
var cn = new 
System.Data.SqlClient.SqlConnection(your_sql_connection_string);
var da = new System.Data.SqlClient.SqlDataAdapter(SQL.ToString(), cn);
var datatbl = new DataTable();
da.SelectCommand.Parameters.Add("@GivenGroup", SqlDbType.Int).Value = 1; // use parameterization always.
try {
    da.SelectCommand.Connection.Open();
    da.Fill(datatbl);
}
catch (Exception ex)
{
    // error handling here
}
finally
{
    cn.Close();
    cn.Dispose();
    da.Dispose();
}
// read from datatable
foreach (DataRow row in datatbl.Rows)
{
    Console.WriteLine(row["G_Id"].ToString());
}

可能包含错误。

您使用的是EF的代码优先方法还是数据库优先方法?我使用的是数据库优先方法请添加类结构,让我们开始帮助您。:)类结构如给定的关系方案所示(ID为int作为prima