2012-03-29 70 views
1

我想从表中选择项目,这些项目有关系属性,我可以投影他们,如果他们可以为空(即像左连接)?如果不是我能如何解决这个问题?LINQ投影与空值的关系属性

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”。在此上下文中仅支持 实体类型,枚举类型或基元类型。

+0

@All:仔细看看错误,我怀疑它完全在其他地方。注意它说'null常量值',我看不出有什么与常量在这里。 – Rawling 2012-03-29 12:15:37

+0

什么是异常类型? – jrummell 2012-03-29 15:22:13

回答

0

你需要投你nullStruct

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 }); 
+0

对不起“Struct”是类的错误名称,实际上Struct是类。 – baio 2012-03-29 12:00:54

+0

然后只要删除'?'。 – DaveShaw 2012-03-29 12:01:42

+0

仍然没有工作,同样的例外 – baio 2012-03-29 12:02:42

1

你为什么不使用左连接?

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 
    } 
} 
+0

我试图建立像LINQ entyities和我的模型之间的映射,在左连接的情况下会是丑陋的。正如你可以看到2行原始代码打出5行左连接。从代码可读性这点不愉快。 – baio 2012-03-29 12:50:02

+0

@baio,如果你想减少只在一行上放置匿名类型初始值设定项的行数'select new {Id = product.Id,Producer = producer!= null?新的MyProducer {Id = producer.Id}:null}' – RePierre 2012-03-29 13:11:30

+0

好吧我明白你的意思是说,但实际上这只是代码的例子,真正的代码是以特定的方式编写的,我不想拒绝它, 如果可能。 – baio 2012-03-29 13:19:18

0

不知道这是否是处理可能为null关系的投影的唯一方法,但这是我过去如何做的。你创建你的新对象,然后在设置属性时适当地检查null。这个解决方案唯一的问题是,你现在必须检查'producer'的'id'属性是否为'0'以知道关系是否为空。如果有更好的方法来处理这个问题,我会喜欢它,如果有人将它发布在这里。

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();