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字符串。
有什么想法吗?
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"
};