如何在Lambda Expression

时间:2018-02-27 04:01:35

标签: c#

我想通过嵌套的接口类型查询序列(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使用接口,例如查询数据和基于接口的修改值然后保存到数据库,创建一些基于接口的常见查询扩展。如果可以的话,可以减少许多代码,并且项目将更容易维护。

即使字段名称不同,也可以在实体模型和界面中查询来自数据库的相同类型的数据。

2 个答案:

答案 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"));