实体框架7 /核心代码优先映射到存储过程

时间:2017-03-29 01:19:45

标签: entity-framework-6

我是Entity Framework 7代码优先的新手,遇到了存储过程的映射问题。

下面是两个类cityid是关系属性:

public class CityList
{
        [Key]
        public int CityId { get; set; }
        [Required]
        [MaxLength(50)]
        public string CityName { get; set; }
        [MaxLength(200)]
        public string CityDescription { get; set; }
        public ICollection<PointOfInterestList> PointOfInterestList { get; set; } = new List<PointOfInterestList>();
}

public class PointOfInterestList
{
        [Key]
        public int PointsofInterestId { get; set; }
        [Required]
        [MaxLength(50)]
        public string PointsofInterestName { get; set; }
        [MaxLength(200)]
        public string PointsofInterestDescription { get; set; }
        [ForeignKey("CityId")]
        public CityList CityList { get; set; }
        public int CityId { get; set; }
}

使用DbContext从存储过程CityList填充GetCity对象:

var returnlist = _context.CitiesList.FromSql("GetCity @p0", CityId).ToList();

存储过程代码:

CREATE PROCEDURE [GetCity]
    (@CityId INT = 0)
AS
BEGIN
    IF @CityId = 0
        SET @CityId = NULL

    SELECT 
        c.Id CityId, C.Description CityDescription, C.Name CityName--,c.Country
        ,p.Id PointsofInterestId, p.Name PointsofInterestName, p.Description PointsofInterestDescription
    FROM 
        dbo.Cities c 
    INNER JOIN 
        dbo.PointOfInterest p ON p.CityId = c.Id
    WHERE 
        c.Id = ISNULL(@CityId, c.Id)
END

执行存储过程并填充CityList集合,但每个PointOfInterestList对象中的CityList集合不会与存储过程结果一起映射。

如果我错过任何一步,请告诉我。

1 个答案:

答案 0 :(得分:0)

当您通过存储过程进行映射时,它不够智能,无法了解任何包含正在执行的操作(因为您无法执行.Include(...))。它只知道您直接映射到的实体上的直接字段。因此,您能够解决此问题的唯一方法是创建自己的DTO,其中包含标题和行,然后有一个自定义映射将数据推送到适当的实体,同时必须处理自己重复标题数据。 (即如果你有2行,你需要1个标题,然后将两行添加到该标题。基于PK的唯一性将起作用。)

编辑 - 示例:

var list = context.Database.SqlQuery<MyCustomRowDto>("...").ToList();

然后当你调用存储过程时:

var data = new Dictionary<int, CityList>();

foreach (var item in list) {
   CityList entity;
   if (!data.TryGet(item.CityId, out entity)) {
      entity = new CityList() { CityId = item.CityId, CityName = item.CityName ..., PointOfInterestList = new List<PointOfInterestList>() };
      data.Add(item.CityId, entity);
   }
   entity.PointOfInterest.Add(new PointOfInterestList() { PointOfInterestId = item.PointofInterestId, ..., CityId = item.CityId, CityList = entity
}

return data.Select(a => a.Value).ToList();

然后,您需要某种带有主键字典的映射层。像这样:

String html = "<div class=\"1st\">\n" +
                        "<p>\n" +
                        "<h3>Numérotation : </h3>\n" +
                        "Numéro d'arrêt : 5216\n" +
                        "<br />\n" +
                        "Numéro NOR : 63066\n" +
                    "</div>";

 Document doc = Jsoup.parse(html);
 Elements divs = doc.select("div.1st");
 for(Element e : divs){
      System.out.println(e.ownText());
 }