C# LINQ导航属性多个源

C# LINQ导航属性多个源,c#,sql,linq,linq-to-entities,linq-to-objects,C#,Sql,Linq,Linq To Entities,Linq To Objects,我有一个存储不同位置的数据库。根据位置的类型,唯一的详细信息存储在与常用属性不同的表中,即名称、坐标、描述存储在位置表中,而人口存储在CityDetails表中。 这些表通过特定详细信息表中的FK连接。 由于有不止一个特定的详细信息表,我正在琢磨如何查询这些多个表。 我的位置对象如下所示: [Table("Locations")] public class LocationData { public Guid Id { get; set; } // multiple diffe

我有一个存储不同位置的数据库。根据位置的类型,唯一的详细信息存储在与常用属性不同的表中,即名称、坐标、描述存储在位置表中,而人口存储在CityDetails表中。 这些表通过特定详细信息表中的FK连接。 由于有不止一个特定的详细信息表,我正在琢磨如何查询这些多个表。 我的位置对象如下所示:

[Table("Locations")]
public class LocationData
{
    public Guid Id { get; set; }

    // multiple different properties here.

    public string Type { get; set; }

    public DetailsData { get; set; }
}
public abstract class DetailsData 
{
    [Key, ForeignKey("Location")]
    public Guid { get; set; }

    public LocationData Location { get; set; }
}
根据Type属性,我可以查看必须查询的详细信息表。详细信息表至少如下所示:

[Table("Locations")]
public class LocationData
{
    public Guid Id { get; set; }

    // multiple different properties here.

    public string Type { get; set; }

    public DetailsData { get; set; }
}
public abstract class DetailsData 
{
    [Key, ForeignKey("Location")]
    public Guid { get; set; }

    public LocationData Location { get; set; }
}
然后,表示位置类型的每个表都从DetailsData类继承,并配置为使用每个具体类继承层次结构的表。 下面是一个特定详细信息表的示例:

[Table("CityDetails")]
public class CityDetailsData : DetailsData
{
    public string Planet { get; set; }

    public int Population { get; set; }
}
如何在Location类中填充DetailsData属性。以下是我当前的LINQ查询:

from l in Locations
select new
{
    Id = l.Id,
    Name = l.Name,
    Description = l.Description,
    Coordinates = l.Coordinates,
    Type = l.Type,
    DetailsData = CityDetails // Here lies the problem. How can I populate this property properly?
}

好的,我假设您的详细信息表都有不同的列集,希望能够使用IEnumerable实例,并且希望能够直接访问返回的任何详细信息表对象的实例的属性

那是个强悍的家伙。基本上有三种方法可以为未知类型的对象编写代码:

给它一个对象类型。 使所有细节表从公共接口继承,并使CityDetails成为实现该接口的对象。 使用泛型类型,这意味着您最终指定了类型,但您可以将该决策向上推到所实现类型的声明者。 使用System.Object意味着您需要将所有DetailsData对象强制转换为所需的类型,或者使用反射来访问它们的属性,而使用接口意味着您可以直接访问某些属性,但可能不是您想要的所有属性

我认为泛型可能是最好的混合解决方案

我会这样做:

[Table("Locations")]
public class LocationData
{
    public Guid Id { get; set; }

    // multiple different properties here.

    public string Type { get; set; }

    public DetailsData { get; set; }
}
public abstract class DetailsData 
{
    [Key, ForeignKey("Location")]
    public Guid { get; set; }

    public LocationData Location { get; set; }
}
承认没有完美的解决方案。 如果您使用的是ASP.NET MVC,请定义类似于ViewModel的类,而不是像在示例代码中那样创建匿名类型:

public class LocationViewModel<TDetailsData>
{
    public Guid Id { get; set; }

    // multiple different properties here.

    public string Type { get; set; }

    public TDetailsData DetailsData { get; set; }
}
如果需要保留这些对象的IEnumerable,请定义一个接口ILocationDataViewModel和另一个接口ILocationDataViewModel,使LocationViewModel实现这两个接口,并根据情况使用IEnumerable或IEnumerable等


如果我理解正确,您希望动态确定类型并动态处理它。那样的话,你可以和我一起去。我还没有测试过这段代码,但是你可以这样想

        public DetailsData GetDetailsData(Type t) 
        {
            dynamic typVal = new ExpandoObject();

            if(t == typeof(CityDetails))
            {
                typVal = new CityDetails();
            }
            // add other types

            return (DetailsData)PopulateDetailsData(typVal);
        }

        public DetailsData PopulateDetailsData(CityDetails cd)
        {
            cd.Planet = new CityDetails().Planet;
            return cd;
        }

        // Add other type related methods with same 
        // signature with input parameter differentiated by types
        // for example
        public DetailsData PopulateDetailsData(TownDetails td)
        {
            td.Income = new TownDetails().Income;
            return td;
        }
在查询中,您可以有如下内容

from l in Locations
select new
{
    Id = l.Id,
    Name = l.Name,
    Description = l.Description,
    Coordinates = l.Coordinates,
    Type = l.Type,
    DetailsData = GetDetailsData(l.Type)
}

我假设您所有的特定明细表都有不同的列集?是的,它们有。我用一个例子更新了问题。请参阅我更新的问题。每个细节表都有一组不同的属性/列,但都继承自同一抽象类DetailsData。此抽象类也是在主LocationData类中用作属性类型的类的类型。我要补充的是,这些数据将被转换成一种稍有不同的数据类型,用于程序的其他部分。基本上,我需要一个带有LocationData的IEnumerable。详细信息从不同的详细信息表之一填充。如果在使用LocationData的特定实例时不关心intellisense或易于访问属性值,难道你不能编写一个助手方法,使用参数类型来检查适当的细节表并返回一个DetailsData吗?不,我不太了解intellisense。我的工作流程如下:1。查询位置表。2.查询适当的详细信息表并将其存储在details属性中。3.将其返回到存储库。4.将其传递到转换器5。将转换后的数据返回给用户。我试试你的主意。它是如此简单,我完全忘记了它…@Ruhrpottpatriot LOL!我给了你一个过于复杂的答案,因为我想,问题不可能那么简单!他一定在要求一些非常微妙的东西!可能就是这么简单。问题是:我创建了一个请求,让服务经理来处理,这与存储库的工作方式有关,因为它可以使用多个源,即基于请求和服务经理的数据库或webApi数据。对数据库的请求是Func表达式。我不确定我是否可以做一些简单的事情,比如方法调用。或者更好:我确信这必须在林克完成。好吧,我错过了树木的森林。。。英雄联盟