在LINQ中动态选择表

本文关键字:选择 动态 LINQ | 更新日期: 2023-09-27 18:16:13

我正在开发一个多元文化的网站,在某些情况下,我需要能够根据所选的文化从不同的表中读取数据。下面是一个例子:

IEnumerable<NewsEN> dataEN;
IEnumerable<NewsRU> dataRU;
if (Thread.CurrentThread.CurrentUICulture.ToString() == "en")
  dataEN = db.NewsEN.ToList();
else
  data = db.NewsRU.ToList();
//Won't let me do this because implicit conversion isn't allowed here
var result = dataEN != null ? data : dataRU;
//Here's the important part where I want to stick the result in
var model = result.Select(....

(我知道这看起来很恶心)

我目前尝试的是Automapper。它不仅不起作用,而且对于这样一个简单的任务来说,它似乎也太过了,所以我们分道扬镳了。我也考虑过动态Linq库,但还没有尝试。
第三种选择是执行sql命令,将表名作为变量,我可以从If语句中获得。

而且,有大约20个方法将不得不依赖于这些代码——我应该期待一些智能的存储库模式吗?

在LINQ中动态选择表

在NewsEN和NewsRU上实现一个接口,使用IEnumerable<INews>IQueryable<INews>。如果你想将查询提取为方法,你可以在约束为INews的情况下使用泛型。

的例子:

interface INews
{
    DateTime PublishDate { get; }
}
class NewsRU : INews
{
     public string Text {get; set; }
     public DateTime PublishDate {get; set;}
}
...
public static void IQueryable<T> GetTodaysNews<T>(this IQueryable<T> source) where T:INews
{
    return from n in source
           where n.PublishDate > DateTime.Now.Date
           select n;
}
...
result.GetTodaysNews(); //whatever result is it will work

还要注意,您应该考虑有一个新闻表,并将语言作为该表中的一列。虽然有时使用不同的表会更好,但更多情况下,您需要将数据放在一个表中,并将语言作为一个列。

这些类不继承任何东西。我先用代码,所以我只创建了NewsRU类来添加表,但没有添加名称这两个类完全相同。


重构数据库方案。目前你把NewsENNewsRU当作两个不同的对象,尽管它们包含完全相同的属性。因此,我建议不要为NewsENNewsRU都创建一个表,而只使用一个表(News),并添加一个名为"Culture"的额外字段。

你可以这样做:

var culture = Thread.CurrentThread.CurrentUICulture.ToString();
var data = db.News.Where(x => x.Culture == culture);

这将根据当前区域性获取News记录。这也使得以后可以扩展到其他文化。您所要做的就是在添加News记录时将区域性设置为其他内容。