3

我有一个与Product表没有定义关系的translation表。我向POCO添加了一个Translation属性作为.Product[NotMapped]

**我的产品 POCO:**

public partial class Product
{
    public int ProductID { get; set; }

    public double Price { get; set; }

    [NotMapped]
    public virtual Translation Translation{ get; set; }

    /** Other properties **/
}

我还有一张Translation桌子,就像名字说的那样,它包含所有的翻译。现在,translation可以通过提供三个参数从数据库中检索权利LanguageIDTranslationOriginIDValueID

  • LanguageID: 来自用户定义的语言的 ID。
  • TranslationOriginID:简单地说,'哪个表包含我想要翻译的实体?换句话说,这个 ID 指向另一个包含所有可能来源的表。原点是可以具有translation. 例如:本例中的原点是Product
  • ValueID:这是我想要的实体的 ID translation

我的TranslationPOCO:

public partial class Translation
{
    public int TranslationID { get; set; }

    public byte LanguageID { get; set; }

    public short TranslationOriginID { get; set; }

    public int ValueID { get; set; }

    public string TranslationValue { get; set; }

   /** Other properties **/

    public virtual TranslationOrigin TranslationOrigin { get; set; }

    public virtual Language Language { get; set; }
}

当我想用它们检索所有产品时Translation,我执行以下代码:

List<Product> products = context.Products.ToList();

 foreach (Product product in products)
 {
      product.Translation = context.Translations.FirstOrDefault(y => y.LanguageID == 1 && y.TranslationOriginID == 2 && y.ValueID == product.ProductID);
 }

如您所见,我为列表中的每个产品执行另一个查询以获取翻译。

我的问题:是否有可能在一个查询中获得所有产品及其翻译?甚至当我选择一个product?

我已经尝试过一个.Include()和一个.Select()。它没有工作,也许我做错了什么?这个方法我也试过了,也没用。

顺便说一句,我将 Entity Framework 5 与 .NET 4 一起使用(所以,Entity Framework 4.4)。

提前致谢。

问候 Loetn


回答

通过Ed Chapel给出的示例,我想出了一个解决方案。

return (from p in context.Products
            join t in context.Translations
            on new
            {
                Id = p.ProductID,
                langId = languageID,
                tOriginId = translationOriginID
            }
            equals new
            {
                Id = d.ValueID,
                langId = d.LanguageID,
                tOriginId = d.TranslationOriginID
            }
            into other
            from x in other.DefaultIfEmpty()
            select new
            {
                Product = p,
                Translation = x
            })
            .ToList().ConvertAll(x => new Product()
            {
                Code = x.Product.Code,
                Translation = x.Translation,
                /** Other properties **/
            });
4

3 回答 3

2

在大多数情况下,我不喜欢正确的 LINQ。但是,joinLINQ 比扩展方法容易的一种情况是:

from p in context.Products
join t in context.Translations
    on t.ValueID equals p.ValueID
       && t.LanguageID == 1
       && t.TranslationOriginID == 2
    into joinT
from x in joinT
select new { 
               Product = p,
               Translation = t,
           };

然后循环遍历结果设置x.Product.Translation = x.Translation

于 2013-09-26T07:35:06.980 回答
0

通过Ed Chapel作为解决方案提出的示例,我想出了这个。

 return (from p in context.Products
                join t in context.Translations
                on new
                {
                    Id = p.ProductID,
                    langId = languageID,
                    tOriginId = translationOriginID
                }
                equals new
                {
                    Id = d.ValueID,
                    langId = d.LanguageID,
                    tOriginId = d.TranslationOriginID
                }
                into other
                from x in other.DefaultIfEmpty()
                select new
                {
                    Product = p,
                    Translation = x
                })
                .ToList().ConvertAll(x => new Product()
                {
                    Code = x.Product.Code,
                    Translation = x.Translation,
                    /** Other properties **/
                });
于 2013-09-26T14:17:11.710 回答
0

首先,您应该意识到您的翻译表的结构不像 dba 想要的那样
您有非强制关系,因为根据 OriginId 您的 valueId 引用不同的表。
因此,您不能使用延迟加载或 EF 中的包含。
在这一点上,我最好的想法是手动加入匿名类型的表(包括你的 originId)。之后您可以遍历结果以设置翻译属性

结果将如下所示:

var data =   from p in context.Products
             join pt in context.Translations on new{p.Id,2} equals new {pt.ValueId, pt.OriginId} into trans
             select new {p, trans};
var result = data.ToList().Select( a =>
                {
                    a.p.Translations = a.trans;
                    return a.p;
                }).ToList();
于 2013-09-26T07:45:58.267 回答