0

所以这是设置

您有一个命名空间 DAL 和一个命名空间 DTO(在不同的程序集中)。两者都包含一个类 Foo。我试图做的是在 DTO 类型上指定 EF 包含并将它们转换为 DAL 类型。

我们有以下来自前端的集合:

using DTO;

public class GetFooById : Request
{
    public GetFooById()
    {
        IncludeProperties = new HashSet<Expression<Func<object, object>>>
                    {
                        x  => ((Foo)x).Bar, //DTO.Foo, when debugging is DAL.Foo
                        x => ((Foo)x).Foobars,
                    };
    }
}

我们在另一个程序集中使用这个集合,如下所示:

IQueryable<object> query = Context.Foos;

foreach (var expr in request.IncludeProperties)
{
        query = query.Include(expr);
}

var foo = query.First(x => x.Id == request.Id);

奇怪的是,这段代码正在编译和执行,但包含的属性为空。当我调试并将鼠标悬停在这部分上时:x => ((Foo)x).Bar调试器说Foo是类型:DAL.Foo 而不是包含的 DTO.Foo。

这是因为表达式编译在一个文件中,我们没有包含到 DTO,但我们有一个包含到 DAL?这不是 c# 中的错误吗?

这是 C# 中的预期行为吗?

项目框架是 4.0,但我正在安装 4.5 进行编译。

4

2 回答 2

1

这不是由 C# 引起的。您忽略了 的结果query.Include(expr);,因此该Include表达式实际上并没有得到应用。只要它仍然未被使用,它就不会引起问题:即使在常规 C# 代码(没有表达式树)中,如果你有一个 type 的对象A,那么将它转换为一个完全不同的类型Busing(B)(object)a显然是行不通的,但这会在运行时被检测到,所以只有当代码实际被调用时。

此外,据我所知,实体框架目前不支持具有相同名称的多种类型。它按名称查找类型,DAL.Foo并且DTO.Foo具有相同的名称。EF 知道的类型是它最终使用的类型。你不应该依赖这个。

于 2013-08-20T09:02:31.203 回答
0

由于 DAL.Foo (在当前程序集中)比 DTO.Foo (在包含的程序集中)更接近(在当前程序集中),因此编译器首先选择它。这是预期和一致的行为,而不是错误。您需要明确指定名称,因此请更改此名称

x  => ((Foo)x).Bar, 

 x  => ((DTO.Foo)x).Bar, 
于 2013-08-20T08:51:30.173 回答