我有EF模型类,我决定用一个bool
属性扩展该类:
class A
{
public int Id { get; set; }
public string Value { get; set; }
}
class A_DTO : A
{
public bool BoolProp { get; set; }
}
class C
{
public int Id { get; set; }
public int A_Id { get; set; }
}
然后我编写了一个方法,该方法将返回与其他A
集合连接的C
集合,其中包含A< => C映射(在实际示例中,它包含一些SystemId
和linq查询将由2列连接)并返回A_DTO
集合:
internal IQueryable<A_DTO> MyMethod() =>
from a in dbContext.A
join c in dbContext.A_C_Mapping
on a.Id equals c.A_Id into g
from cc in gg.DefaultIfEmpty()
select new A_DTO
{
Id = a.Id,
Value = a.Value,
BoolProp = cc.A_Id != null //<- will be always true, well, that what says warning message
}
(dbContext
是我的EF上下文对象)
当然由于cc.A_Id
不是可空的int
,会出现警告信息,说
&#34;表达式的结果始终为
'true'
,因为类型int
的值永远不会等于null
类型的int?
值#34;
这是真的,但实际上我得到的结果完全正确,因为我的左外连接返回null
时C
集合中缺少映射。
所以问题是:这样做是否正确并保持原样,或者我需要以另一种方式实现它?
答案 0 :(得分:2)
根据DefaultIfEmpty method definition,以下代码段是等效的:
List<C> list = new List<C>() { }; // empty list
List<C> listDefault = list.DefaultIfEmpty().ToList();
和
List<C> listDefault = new List<C>() { null }; // Since default(C) is null
因此,当您使用g.DefaultIfEmpty()时,您将获得一个唯一的cc对象,该对象为null,因此该行:
BoolProp = cc.A_Id != null
将抛出NullReferenceException,因为cc为null。
最后似乎应该是:
BoolProp = cc != null
此外还有一个小例子,通过单元测试证明了差异:
[TestMethod]
public void TestMethod_DefaultifEmpty()
{
ListA = new List<A>()
{
new A { Id=1, Value="111" },
new A { Id=2, Value="222" },
};
ListC = new List<C>()
{
new C { Id=1, A_Id=1 }
};
Assert.AreEqual(2, MyMethod().Count());
}
public List<A> ListA { get; set; }
public List<C> ListC { get; set; }
public IEnumerable<A_DTO> MyMethod() =>
from a in ListA
join c in ListC
on a.Id equals c.A_Id into g
from cc in g.DefaultIfEmpty()
select new A_DTO
{
Id = a.Id,
Value = a.Value,
//BoolProp = cc.A_Id != null
BoolProp = cc != null // replace by previous line to see the difference
};
答案 1 :(得分:0)
如果cc.A_Id永远不会变为空并且您想要为BoolProp设置值,那么您可以通过将您的选择更改为以下内容来删除警告:
select new A_DTO
{
Id = a.Id,
Value = a.Value,
BoolProp = true
}
答案 2 :(得分:0)
Value Types
即使您未使用LEFT OUTER JOIN到Nullable
,也会始终拥有默认值(将其声明为LINQ
时的例外情况),即使它们未被初始化也是如此。因此A_ID
将始终具有值,BoolProp
将始终为真。
另一方面,Reference Types
将默认为NULL
。