c#实体框架选择派生子项

本文关键字:派生 选择 实体 框架 | 更新日期: 2023-09-27 18:25:41

所以我需要选择一个Task()对象,包括它的Attachments()对象和Include(),如下所示:

var tmp = cntx.Tasks.Include( at => at.Attachments ).FirstOrDefault(t => t.Id == id ); 

它运行得很好,MVC api控制器可以将它序列化为json,列出了它的所有Attachmnet,基本上它运行得非常好。

现在我的问题是,我在Task() 中需要3个额外的字符串属性(为了更清楚的例子,我只使用下面的+1个字符串)

 public class TaskView : DataClasses.Task {
    public string BusinessName { get; set; }
}

这些道具不是Task()的导航属性,事实上它来自其他一些表。现在,我可以将上一个查询与表连接起来,但我不知道如何选择上一个完全填充的Task对象及其所有导航Attachment()对象,并将其强制转换为TaskView obj,并添加BusinessName字符串。

有什么想法吗?

c#实体框架选择派生子项

public class TaskView : DataClasses.Task {
    public string BusinessName { get; set; }
    // Create constructor for Task
    public TaskView(DataClasses.Task task)
    {
       // Copy properties here
    }
}

然后你可以这样做:

var tmp = cntx.Tasks
  .Include(at => at.Attachments)
  .Where(t => t.Id == id)
  .Select(t=> new TaskView(t) { BusinessName=...})
  .FirstOrDefault();

或者,您可以在TaskView上创建一个属性,从TaskView设置(并可能获取)Task,然后在LINQ查询中设置它。

或者这样做:

public class TaskView {
    public string BusinessName { get; set; }
    public DataClasses.Task Task { get; set;}
}

然后:

var tmp = cntx.Tasks
  .Include(at => at.Attachments)
  .Where(t => t.Id == id)
  .Select(t=> new TaskView { Task=t,BusinessName=...})
  .FirstOrDefault();
基类实例不能"强制转换"为派生类实例。您需要创建一个新的TaskView实例,并复制源Task的所有属性。

如果你能负担得起,那么切换到遏制比像这样的继承要好得多

public class TaskView
{
    public Task Task { get; set; }
    public string BusinessName { get; set; }
    // ...
}

不要将实体与传输层及其视图混淆。更好的解决方案,如果你为传输层创建两个这样的类:

public class TaskDto 
{
  public long Id {get; set;}
  public List<AttachmentsDto> Attachments {get; set;}
}
public class AttachmentsDto 
{
  public long Id {get; set;}
}

另外两个用于视图,没有像以前那样继承。此外,还需要创建一些帮助类,用于将实体映射到dto和从dto映射到视图。

var dtos = cntx.Tasks.Include( at => at.Attachments ).FirstOrDefault(t => t.Id == id ).Select(x => new TaskDto 
{
  Id = x.Id,
  Attachments = x.Attachments.Select(y => new AttachmentsDto { Id = y.Id }).ToList()
});

如果我正确理解您的问题,请尝试使用select查询。
类似于:

var tmp = from o in cntx.Tasks.Include( at => at.Attachments ) 
were (o.id == id) 
select new TaskView()
{
 //Properties here
 //e.g
 Id = o.Id,
 Attachments = o.Attachments,
 BusinessName = "YourBusinessName"
};