我想通过嵌套的接口类型查询序列(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));
但这只适用于类和接口中的Property是同一类型的情况。比如,
使用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
和{{1} }。将包含具有不同名称的基本列的表放入一个DateTimeCreated
时会出现问题。在数据库和项目中更改这些列名称将很困难并导致一些新问题,有许多Entity Data Model
分支,并且在许多模块中使用了一些表。所以我创建了一个包含所有这些基本列的接口,并将枚举字段从数字类型(在数据库中)更改为枚举类型(在项目中),并让EF生成的类实现此接口,如果列名和类型不相同,则实现显式接口中的属性,因此可以忽略对原始项目的影响。
这确实解决了问题,但是很难通过EF使用接口,例如查询数据和基于接口的修改值然后保存到数据库,创建一些基于接口的常见查询扩展。如果可以的话,可以减少许多代码,并且项目将更容易维护。
即使字段名称不同,也可以在实体模型和界面中查询来自数据库的相同类型的数据。
答案 0 :(得分:0)
您可以使用ReplaySubject
过滤仅可分配给某个类型的那些。
示例:
OfType
答案 1 :(得分:0)
技术解释和解决方法是,您可以在不进行转换的情况下比较Nullable int和Nullable枚举(这与comparing an int and an enum不同!)。
在这篇文章的最后,你会找到一个如何解决这个问题的例子。
然而,更有趣的问题是为什么你有
带有DataModel
成员的班级public int? Value1
实施的
接口IData
声明TypeInEnum? Value1
成员?
我认为如果DataModel
实现IData
,它也应该Value1
类型为TypeInEnum?
,即:
public class DataModel : IData
{
public TypeInEnum? Value1 { get; set; }
...
}
您可以找到重构代码here
的示例至于technicahl解决方案:
使用强制修改来查看您的代码:
https://dotnetfiddle.net/8MqXnr
var query = source.Where(item => item.Value1.HasValue).Where(item => (int)(item.Value1.Value) == 1); //item is DataModel
var query1 = source.Where(item => item.Value1.HasValue).Where(item => item.Value1.Value == (int)TypeInEnum.A); //item is IData
var eq = query.SequenceEqual(query1);
Console.WriteLine(String.Format("results: {0}",eq? "Equal": "Not equal"));