我有一个Product
表,没有与translation
表定义的关系。我将Translation
属性添加到Product
POCO [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
:LanguageID
,TranslationOriginID
和ValueID
。
LanguageID
:用户定义语言的ID。 TranslationOriginID
:简单地说,'哪个表包含我想要翻译的实体?'换句话说,此ID指向包含所有可能来源的另一个表。原点是可以具有translation
的表/实体。例如:此示例中的原点是Product
。 ValueID
:这是我想要translation
的实体的ID。 我的Translation
POCO:
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()
。它没用,也许我做错了什么?
我也试过this method,也没用。
顺便说一句,我使用.NET 4实体框架5(因此,实体框架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 **/
});
答案 0 :(得分:2)
在大多数情况下,我不喜欢正确的LINQ。但是,join
是LINQ比扩展方法容易的一种情况:
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
。
答案 1 :(得分: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();
答案 2 :(得分: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 **/
});