我有一个映射到 Entity Framework 数据库的对象。这是一个相当大的对象,在获取它们的列表时,我只需要数据的一个子集。
问题是我有两个我需要的只读属性,它们在 TypeId 字段周围有一些重要的逻辑。这是一个例子:
这是我映射到实体的类
public class MyBigObject
{
public int Id { get; set; }
public string Name { get; set; }
public int OwnerId { get; set; }
public string TypeId { get; set; }
public bool IsFoo
{
get { /* complicated logic here for checking if TypeId IsFoo */ }
}
public bool IsBar
{
get { /* complicated logic here for checking if TypeId IsBar */ }
}
/* snip about 30 other columns */
}
这一切都很好,花花公子,非常适合拉取该对象的列表。但是,随着时间的推移,对象变大了,我想减少实体检索的数据量。为此,我们创建了一个未映射到实体的新 DTO 类。
public class MyBigObjectItem
{
public int Id { get; set; }
public string Name { get; set; }
public string TypeId { get; set; }
public bool IsFoo { get; set; }
public bool IsBar { get; set; }
public bool HasObject1 { get; set; }
public bool HasObject2 { get; set; }
}
它只是一个非常简单的 getter 和 setter 容器。
然后,对于我的 linq 查询,我有这样的东西
public Task<List<MyBigObjectItem>> GetMyBigObjectItemsAsync(int ownerId, CancellationToken cancellationToken = default(CancellationToken))
{
return (
from obj in DataContext.MyBigObject
join object1 in DataContext.SomeObject1 on obj.Id equals object1.ObjectId into object1items
join object2 in DataContext.SomeObject2 on obj.Id equals object2.ObjectId into object2items
where obj.OwnerId = ownerId
orderby obj.Name
select new MyBigObjectItem
{
Id = obj.Id,
Name = obj.Name,
TypeId = obj.TypeId,
IsFoo = obj.IsFoo,
IsBar = obj.IsBar,
HasObject1 = object1items.Any(),
HasObject2 = object2items.Any()
}
).ToListAsync(cancellationToken);
}
该查询中有很多内容,但我想给出一个准确的示例来说明我在做什么。我们正在加入我们有一对多关系的另外两个对象。我只需要知道是否存在任何关系。
麻烦来自 IsFoo = obj.IsFoo,
和 IsBar = obj.IsBar,
行,其中 Intellitrace 显示错误:
The specified type member 'IsFoo' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported." (System.NotSupportedException)
关于如何使这项工作有任何想法,还是我注定要获取完整对象的列表,然后将它们转换为我的 DTO?
最佳答案
... or am I doomed to get the list of full objects and then transform those into my DTO?
差不多。在评估查询之前所做的任何事情都是 Entity Framework 可以转换为 SQL 的事情,这排除了任何自定义属性,例如您创建的自定义属性。您唯一真正的选择是创建一个存储过程来执行这些属性中包含的逻辑,只返回 IsFoo
和 IsBar
的结果 bool 值,然后使用该 SP 检索你的对象。根据此查询的复杂性,无论如何这都可能是一个不错的举措。
关于c# - 将只读属性分配给 Entity Framework 中的新对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28568047/