嵌套Linq查询Microsoft Azure

本文关键字:Azure Microsoft 查询 Linq 嵌套 | 更新日期: 2023-09-27 18:26:37

我的azure模型中有三个模型。一个模型基本上映射了另外两个。这是我的型号

public class Organization : EntityModel
{
    public String Id
    {
        get
        {
            return this.RowKey;
        }
        set
        {
            this.RowKey = value;
        }
    }
    ......
}
public class OrganizationGroup : EntityModel
{
    public String Id
    {
        get
        {
            return this.RowKey;
        }
        set
        {
            this.RowKey = value;
        }
    }
    .......
}

现在这里是映射类

class OrganizationGroupMapping : EntityModel
{
    public String OrganizationId
    {
        get
        {
            return this.PartitionKey;
        }
        set
        {
            this.PartitionKey = value;
        }
    }
    public String OrganizationGroupId
    {
        get
        {
            return this.RowKey;
        }
        set
        {
            this.RowKey = value;
        }
    }
    ....
}

现在我正在尝试创建一个函数,它将为我提供特定组织组中的所有组织。我可以使用for循环,我现在这样做就像这个

    public IEnumerable<Organization> GetOrganizations()
    {
        List<Organization> org = new List<Organization>();
        foreach (OrganizationGroupMapping ogm in OrganizationGroupMapping.GetByOrganizationGroupId(Id))
        {
            org.Add(ogm.GetOrganization());
        }
        return org;
    } 

上面的函数是从OrganizationGroup类调用的。我试着用linq,因为它看起来更干净。但不知道该怎么做。在这方面有什么帮助吗?

嵌套Linq查询Microsoft Azure

您只需要使用System.Linq.Select即可创建一个隐式类型为GetOrganization()的新对象。

public IEnumerable<Organization> GetOrganizations()
{
    var organizations = OrganizationGroupMapping.GetByOrganizationGroupId(Id)
                        .Select(org => ogm.GetOrganization());
    return organizations;
}

您应该学习导航属性和Fluent API

public class Organization
{
    public String Id  { get; set; }
    public virtual ICollection<OrganizationGroup> OrganizationGroups { get; set; }
}
public class OrganizationGroup
{
    public String Id { get; set; }
    public virtual ICollection<Organization> Organizations { get; set; }
}

在您的上下文中:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Organization>().HasMany(l => l.OrganizationGroups).WithMany(t => t.Organizations).Map(m =>
        {
            m.MapLeftKey("OrganizationId");
            m.MapRightKey("OrganizationGroupId");
            m.ToTable("OrganizationGroupMapping ");
        });
    }

用法:

Context.Organizations.Include("OrganizationGroups").ToArray();

在您的代码中,我看不出您是如何在OrganizationGroup和Organization实体上定义分区键的。

我理解一个组织属于一个组织组?如果它是正确的,你可以这样构建你的实体:

因为在处理Azure存储表时,我们有:

  • PartitionKey+rowKey=行的唯一性

为了拥有一个唯一的OrganizationGroup,Id映射分区键,但我们让rowKey为空。

public class OrganizationGroup : TableEntity
{
    public OrganizationGroup()
    {
        this.RowKey = string.Empty;
    }
    public String Id
    {
        get { return this.PartitionKey; }
        set { this.PartitionKey = value; }
    }
}

因为组织属于组织组,所以组织实体的PartitionKey是组织组的分区密钥(请参阅Azure存储表设计指南,查看一对多关系部分):

public class Organization : TableEntity
{
    public String OrganizationGroupId
    {
        get { return this.PartitionKey; }
        set { this.PartitionKey = value; }
    }
    public String Id
    {
        get { return this.RowKey; }
        set { this.RowKey = value; }
    }
}

因此,您不再需要映射表:您可以直接通过OrganizationGroupId(=PartitionKey)检索您的组织:

public static List<Organization> GetByOrganizationGroupId(string organizationGroupId)
{
    var org = new List<Organization>();
    // Retrieve the storage account from the connection string.
    CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
        CloudConfigurationManager.GetSetting("StorageConnectionString"));
    // Create the table client.
    CloudTableClient tableClient = storageAccount.CreateCloudTableClient();
    // Create the CloudTable object that represents the "Organization" table.
    CloudTable organizationTable = tableClient.GetTableReference("Organization");
    // Construct the query operation for all OrganizationGroupMapping entities where PartitionKey="organizationGroupId".
    var query = new TableQuery<Organization>().Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, organizationGroupId));
    // Return the organizations
    return organizationTable.ExecuteQuery(query).ToList();
}