【问题标题】:Add non-relational attribute to EF Entity (Join Operation)将非关系属性添加到 EF 实体(加入操作)
【发布时间】:2015-08-14 18:32:43
【问题描述】:

我有一个如下所述的模型:

public class Student
{
    public int Id { get; set; }
    public string Level { get; set; }
    public string Subject { get; set; }
    public string School { get; set; }
    public int CityId { get; set; } //from City
}

public class City
{
    public int Id { get; set; }
    public string City { get; set; }
    public int StateId { get; set; } //from State
}

public class State
{
    public int Id { get; set; }
    public string State { get; set; }
    public int CountryId { get; set; } //from Country
}

public class Country
{
    public int Id { get; set; }
    public string Country { get; set; }
}

我想查询学生实体,需要将国家(仅限国家)包含到学生模型中。 数据库结构如上,我无法更改数据库表结构。

但我可以编辑上面的 EF 实体。最终我需要将国家作为学生实体的学生信息,这样我就可以绘制 jqGrid 并根据国家对它们进行排序。

【问题讨论】:

    标签: c# mysql entity-framework jqgrid


    【解决方案1】:

    如果你不能修改你的实体类来添加相应的导航属性,你可以试试这个:

    var query = from student in context.Students
                join city in context.Cities on student.CityId equals city.Id
                join state in context.States on city.StateId equals state.Id
                join country in context.Countries on state.CountryId equals country.Id
                select new {
                             StudentId=student.Id,
                             Level=student.Level,
                             ...
                             Country=country.Country
                           };
    

    或许:

               select new {Student=student, Country=country.Country};
    

    如果您的表是相关的,我建议您将导航属性包含到您的模型中:

    public class Student
    {
        public int Id { get; set; }
        //...
        public int CityId { get; set; } //from City
    
        public virtual City City{get;set;}
    }
    
    public class City
    {
        public int Id { get; set; }
        //...
        public int StateId { get; set; } //from State
    
         public virtual City City{get;set;}
         public virtual ICollection<Student> Students{get;set;}
    }
    
    public class State
    {
        public int Id { get; set; }
        //...
        public int CountryId { get; set; } //from Country
        public virtual Country Country {get;set;}
        public virtual ICollection<City> Cities{get;set;}
    }
    
    public class Country
    {
        public int Id { get; set; }
        public string Country { get; set; }
    
        public virtual ICollection<State> States{get;set;}
    }
    

    这不会影响您当前的数据库架构。这种方式更容易使用 student instance 到达 country name (正如@SteveGreene 在他的回答中显示的那样):

    var countryName=student.City.State.Country.Country;
    

    【讨论】:

    • 谢谢!顺便说一句,该国家/地区与 Student 表无关。结果会是学生模型吗?我需要结果是一个学生模型,这样我就可以轻松地对 jqGrid 进行排序。我可以修改学生模型,但不能修改表格。 (CodeFirst 方法)
    • 它是一个匿名类型,所有属性都具有Student + 国家/地区名称
    • 谢谢!我需要学生模型的类型,是否有可能我们可以为县提供任何虚拟属性,所以模型如下所示: public class Student { public int Id { get;放; } 公共字符串级别 { 获取;放; } 公共字符串主题 { 获取;放; } 公共字符串学校 { 得到;放; } 公共 int CityId { 获取;放; } //来自城市 public virtual Country { get;放; } }
    • 也许您可以使用NopMapped 属性来保存国家/地区名称,但我建议您将查询结果保存在DTO 对象中。
    【解决方案2】:

    您可以将其投影到匿名对象或视图模型中:

    var studentWithCountry = context.Student.Where(Id = myVar.Id)
       .Select(s => new { Level = s.Level,
                          Subject = s.Subject,
                          ...
                          Country = s.City.State.Country.Country });
    

    【讨论】:

    • 谢谢!我需要结果作为学生模型。我可以修改学生模型以采用国家关系而不是数据库表。并且它是代码优先的EF方法,因此更改不需要影响数据库
    • 对,要使此功能起作用,您需要添加 octavioccl 建议的导航属性。这些不应该更改数据库,因为您符合实体 + Id 外键约定。除非关系未在数据库中定义。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-09
    • 1970-01-01
    • 2023-02-10
    • 1970-01-01
    相关资源
    最近更新 更多