C# linq查询实体框架中的If控件

C# linq查询实体框架中的If控件,c#,linq,entity-framework,C#,Linq,Entity Framework,嗨 List List=(来自CacheManager.ClaimantList.List中的c) 哪里 c、 全名.Replace(“i”,“i”).Replace(“i”,“i”).ToUpper()包含(searchKey.Replace(“i”,“i”).Replace(“i”,“i”).ToUpper()) ||c.IdentityNumber.Replace(“i”、“İ”).Replace(“ı”、“i”).ToUpper()包含(searchKey.Replace(“i”、“İ”

List List=(来自CacheManager.ClaimantList.List中的c)
哪里
c、 全名.Replace(“i”,“i”).Replace(“i”,“i”).ToUpper()包含(searchKey.Replace(“i”,“i”).Replace(“i”,“i”).ToUpper())
||c.IdentityNumber.Replace(“i”、“İ”).Replace(“ı”、“i”).ToUpper()包含(searchKey.Replace(“i”、“İ”).Replace(“ı”、“i”).ToUpper()
||c.TaxNumber.Replace(“i”,“i”).Replace(“ı”,“i”).ToUpper()包含(searchKey.Replace(“i”,“İ”).Replace(“ı”,“i”).ToUpper())
选择c.Take(20.ToList();
如果Taxnumber为null或“”,则会因为null数据而出现异常

我的问题:

如果Taxnumber为null或“”,如何设置Taxnumber==0

任何帮助都将不胜感激

谢谢。

您可以:

List<Claimant> list = (from c in CacheManager.ClaimantList.List
where 

     c.Fullname.Replace("i", "İ").Replace("ı","I").ToUpper().Contains(searchKey.Replace("i", "İ").Replace("ı", "I").ToUpper())
  || c.IdentityNumber.Replace("i", "İ").Replace("ı", "I").ToUpper().Contains(searchKey.Replace("i", "İ").Replace("ı", "I").ToUpper())
  || c.TaxNumber.Replace("i", "İ").Replace("ı", "I").ToUpper().Contains(searchKey.Replace("i", "İ").Replace("ı", "I").ToUpper())

 select c).Take(20).ToList<Claimant>();

然后使用
taxNumber
变量,而不是列。

如果您只需要某些列,而不需要整个
索赔人
对象,则可以将某些内容放入
选择

from c in CacheManager.ClaimantList.List
let taxNumber = c.TaxNumber == null || c.TaxNumber == "" ? "0" : c.TaxNumber
where ...
现在,您有了一个匿名类型,它有三个字段:原始
全名
、原始
标识号
和修改的
税号


您还可以通过每次调用其构造函数为每个值创建一个新的
索赔人

from c in ClaimantList
where (...)
select new {c.FullName, c.IdentityNumber, TaxNumber = String.IsNullOrEmpty(c.TaxNumber) ? "0" : c.TaxNumber}
(我不知道
的构造函数是什么样的,你可以稍微改变一下,在构造函数中设置那些值,而不是在初始值设定项中。或者你可以编写一个新的构造函数。)如果构造函数做了一些不平凡的事情,那么多次调用它可能会浪费资源

在这两种情况下,将转换(
String.IsNullOrEmpty(TaxNumber)-“0”:TaxNumber
或其他任何内容)放在它自己的函数中的某个地方都是很好的,这样您就可以在以后更改转换操作(见下文),而不必在多个地方重复代码


另一个选择是,您可以使用您拥有的对象,但根据需要更改
TaxNumber
。LINQ并不是最好的方法,因为你基本上是在应用副作用。(LINQ喜欢在新容器中提供正确的数据,而不是更改原始容器中的数据。)您应该真正在LINQ代码之外运行
foreach
,如下所示:

from c in ClaimantList
where (...)
select new Claimant() {FullName = c.FullName, IdentityNumber = c.IdentityNumber, TaxNumber = String.IsNullOrEmpty(c.TaxNumber) ? "0" : c.TaxNumber}

但是,如果您已经这样做了,下一个选项是向
索赔人添加一个方法,该方法会进行以下更改:

List<Claimant> list = from ...
                      where ...
                      select ...

foreach (Claimant claimant in list)
{
    claimant.TaxNumber = NormalizeTaxNumber(claimant.TaxNumber); }
}

// ...

public static string NormalizeTaxNumber(string n)
{
    return String.IsNullOrEmpty(n) ? "0" : n;
}
第一种策略的优点是只需调用一次-第二种策略的优点是它保持原始值仍然可用(在
TaxNumber
属性中),并且如果您有一组
Claimer
对象,您不必记住是否已对其进行了规范化


您还可以使用这两种方法的组合:添加一个新属性
NormalTaxNumber
,该属性在需要时转换
TaxNumber
,并缓存结果,以便不必再次进行转换

public class Claimant
{
    // ...

    public string NormalTaxNumber
    {
        get { return String.IsNullOrEmpty(TaxNumber) ? "0" : TaxNumber; }
    }
}
这只进行一次计算,保持原始数据仍然可用,并且不需要记住您以前是否调用过它。如果
TaxNumber
(原始值)不是只读的,这可能会比它的价值更麻烦,因为您将不得不使缓存的值无效


如果您永远都不需要知道
TaxNumber
最初是空的还是“0”,最好的建议(也是最后一个策略)是尽快转换为您想要的形式,最好是在
claimer
构造函数中,如果
TaxNumber
的值已知的话

如果要从数据库中获取对象,可以在存储过程或视图中对数据库进行转换,从而达到逻辑极限。如果您正在使用LinqToSql获取
对象列表
对象,则视图可能适用于您,但存储的过程可能不适用


我自始至终都假设您希望
TaxNumber
作为字符串提供,而0表示字符串“0”。如果情况并非如此,并且您确实希望转换为
int
(或类似),则上述一些策略仍然有效。您可以在匿名类型中选择转换后的值作为
int
,您可以创建一个新属性
NormalTaxNumber
(使用
int
类型),无论是否缓存,也可以在创建
索赔人
对象时进行转换。显然,您不能用
int
覆盖
字符串
TaxNumber

如果要将
字符串
解析为
int
,则像使用缓存的
NormalTaxNumber
这样的事情会更有价值,因为从
字符串
int
的转换成本更高。(检查
null
实际上是非常快的,但是我认为通过一些不同的选项还是有价值的。)

请注意,如果您不能修改
索赔人
类,那么几乎所有这些都应该仍然可用。您不能编写新的构造函数,但可以编写一个工厂方法,它封装了与构造函数完全相同的行为。您可以添加
NormalizeTaxNumber
作为扩展方法,虽然不能添加属性,但可以添加没有参数的扩展方法,这些参数的工作方式几乎与属性完全相同

我最后的观察是,
“0”
对于缺少的数据来说,不一定比
null
更好。后者中的任何一个更常用于指示缺少的值,尤其是
null
。也许你应该选择其中一个作为默认值(或者反过来应用上述策略中的一个,将其作为唯一的“不适用”值?),如果这只是一个外观问题的话
List<Claimant> list = from ...
                      where ...
                      select ...

foreach (Claimant claimant in list)
{
    claimant.NormalizeTaxNumber();
}

public class Claimant
{
    // ...

    public void NormalizeTaxNumber()
    {
        if (String.IsNullOrEmpty(TaxNumber))
        { TaxNumber = "0"; }
    }
}
public class Claimant
{
    // ...

    public string NormalTaxNumber
    {
        get { return String.IsNullOrEmpty(TaxNumber) ? "0" : TaxNumber; }
    }
}
public class Claimant
{
    // ...

    private string m_normalTaxNumber;

    private string ConvertedTaxNumber
    {
        get { return String.IsNullOrEmpty(TaxNumber) ? "0" : TaxNumber; }
    }

    public string NormalTaxNumber
    {
        get
        {
            if (m_normalTaxNumber == null)
            { m_normalTaxNumber = ConvertedTaxNumber; }
            return m_normalTaxNumber;
        }
    }
}