C# 具有null的LINQ投影关系属性

C# 具有null的LINQ投影关系属性,c#,linq,C#,Linq,我想从表中选择项,这些项具有关系属性,如果它们可以为空(如左连接),我可以投影它们吗?如果不是的话,我如何解决这个问题 class MyProducer { .... } Model model = new Model(); var q = model.Products .Select( p => new { id = p.Id, producer = p.P

我想从表中选择项,这些项具有关系属性,如果它们可以为空(如左连接),我可以投影它们吗?如果不是的话,我如何解决这个问题

class MyProducer
{
  ....
}    

Model model = new Model();
var q = 
    model.Products
    .Select(
      p => 
        new 
        { 
            id = p.Id, 
            producer = p.Producer != null ? new MyProducer { id = p.Producer.Id } : null 
        });

var r = q.ToArray();
当我执行这段代码时,我有一个异常

无法创建类型为“MyProducer”的空常量值。只有 中支持实体类型、枚举类型或基元类型 这个背景


您需要将
null
强制转换为
Struct

Model model = new Model(); 
var q = model.Products.Select(p => new { id = p.Id, producer =  
    p.Producer != null ? new Struct { id = p.Producer.Id } : (Struct)null }); 

您需要将
null
强制转换为
Struct

Model model = new Model(); 
var q = model.Products.Select(p => new { id = p.Id, producer =  
    p.Producer != null ? new Struct { id = p.Producer.Id } : (Struct)null }); 

为什么不使用左连接

using(var model = new Model())
{
    var q = 
    from product in model.Products
    join producer in model.Producers.DefaultIfEmpty()
    on product.ProducerId equals producer.Id
    select new
    {
        Id = product.Id,
        Producer = producer != null ? new MyProducer{ Id = producer.Id} : null
    }
}

为什么不使用左连接

using(var model = new Model())
{
    var q = 
    from product in model.Products
    join producer in model.Producers.DefaultIfEmpty()
    on product.ProducerId equals producer.Id
    select new
    {
        Id = product.Id,
        Producer = producer != null ? new MyProducer{ Id = producer.Id} : null
    }
}

不确定这是否是处理可能为空关系的投影的唯一方法,但我过去就是这样做的。创建新对象,然后在设置属性时适当地检查null。此解决方案的唯一问题是,现在必须检查“producer”的“id”属性是否为“0”,以了解关系是否为null。如果有更好的方法处理这个问题,我希望有人能把它贴在这里

var q = 
    model.Products
    .Select(p => new 
        { 
            id = p.Id, 
            producer = new MyProducer 
            { 
               id = p.Producer == null ? 0 : p.Producer.Id
            }
        }
     );

var r = q.ToArray();

不确定这是否是处理可能为空关系的投影的唯一方法,但我过去就是这样做的。创建新对象,然后在设置属性时适当地检查null。此解决方案的唯一问题是,现在必须检查“producer”的“id”属性是否为“0”,以了解关系是否为null。如果有更好的方法处理这个问题,我希望有人能把它贴在这里

var q = 
    model.Products
    .Select(p => new 
        { 
            id = p.Id, 
            producer = new MyProducer 
            { 
               id = p.Producer == null ? 0 : p.Producer.Id
            }
        }
     );

var r = q.ToArray();

对不起,“Struct”是类的一个坏名字,实际上Struct是类。只是猜测。请尝试使用
default(Struct)
而不是
(Struct)null
。对不起,“Struct”对类来说是个坏名字,实际上Struct就是类。只是猜测而已。尝试
default(Struct)
而不是
(Struct)null
@All:仔细查看错误,我怀疑它完全是在其他地方。请注意,它显示的是
null常量值
,我在这里看不到与常量有关的任何内容。@All:仔细观察错误,我怀疑它完全是在其他地方。注意它说的是
null常量值
,我在这里看不到任何与常量有关的内容。我正在尝试在LINQ entyities和我的模型之间建立某种类似的映射,如果是左连接,它会很难看。正如您所看到的,2行原始代码变成了5行以上的左连接。从代码可读性的角度来看,这是令人不快的。@baio,如果你想减少行数,只需将匿名类型初始值设定项放在一行上
select new{Id=product.Id,Producer=Producer!=null?new MyProducer{Id=Producer.Id}:null}
好的,我理解你的意思,但实际上这只是代码的示例,真正的一个是以特定的方式编写的,如果可能的话,我不想拒绝。我正在尝试在LINQ entyities和我的模型之间建立某种类似映射的东西,如果是左连接,它将是丑陋的。正如您所看到的,2行原始代码变成了5行以上的左连接。从代码可读性的角度来看,这是令人不快的。@baio,如果你想减少行数,只需将匿名类型初始值设定项放在一行上
select new{Id=product.Id,Producer=Producer!=null?new MyProducer{Id=Producer.Id}:null}
好的,我理解你的意思,但实际上这只是代码的示例,真正的一个是以特定的方式写的,如果可能的话,我不想拒绝。