【发布时间】:2018-02-27 04:01:35
【问题描述】:
我想通过嵌套接口类型从序列(IEnumerable和IQueryable)中查询数据,例如,
public interface IData
{
TypeInEnum? Value1 { get; set; }
string Value2 { get; set; }
}
public class DataModel : IData
{
public int? Value1 { get; set; }
public string Value2 { get; set; }
TypeInEnum? IData.Value1
{
get
{
return Value1.HasValue ? (TypeInEnum?)Value1.Value : null;
}
set
{
//ignore enum validation here
this.Value1 = value.HasValue ? (int?)value.Value : null;
}
}
}
public enum TypeInEnum
{
A = 1,
B,
C
}
查询:
//source is IEnumerable<DataModel>
var query = source.Where(item => item.Value1 == 1); //item is DataModel
var query1 = source.Where1(item => item.Value1 == TypeInEnum.A); //item is IData
Assert.IsTrue(query.SequenceEqual(query1));
但这仅适用于类和接口中的属性类型相同的情况。比如,
使用Where时,报错:
System.InvalidOperationException: Rewriting child expression from type 'System.Nullable<TypeInEnum>' to type 'System.Nullable<System.Int32>' is not allowed, because it would change the meaning of the operation. If this is intentional, override 'VisitUnary' and change it to allow this rewrite.
使用Select,错误是:
System.ArgumentException: Expression of type 'System.Nullable<System.Int32>' cannot be used for return type 'System.Nullable<TypeInEnum>'
我不知道在哪里添加Convert。
所有示例代码here
我在这上面浪费了一个月的时间......
已编辑
在我当前使用EntityFramework的项目中,每个表的数据库中都有一些基本列,但我发现一些基本列名称不同,例如CreatedDateTime和DateTimeCreated。将包含不同名称的基本列的表放入一个Entity Data Model 时会出现问题。在数据库和项目中更改这些列名会很困难并且会导致一些新问题,svn 分支很多,并且在许多模块中使用了一些表。所以我创建了一个包含所有这些基本列的接口,并将枚举字段从数字类型(在数据库中)更改为枚举类型(在项目中),并让 EF 生成的类实现这个接口,如果列名和类型不一样,实现接口中显式属性,因此可以忽略对原始项目的影响。
这确实解决了问题,但是通过EF使用接口比较困难,比如基于接口查询数据和修改值然后保存到数据库,创建一些基于接口的通用查询扩展。如果可以的话,可以减少很多代码,项目会更容易维护。
在实体模型和接口中查询相同类型的数据库数据,即使字段名称不同。
【问题讨论】:
-
这样做的目的是什么?我的意思是,对于
Where,例如你可以做source.Where<IData>(item => item.Value1 == TypeInEnum.A);,为什么要使用表达式和自定义访问者? -
@Evk 我想通过EntityFramework从数据库中查询数据,如果属性名和表中的列名不同,会报错。所以我使用访问者将提交的名称“替换”为真实名称。
标签: c#