正在获取具有不同静态值的数据

本文关键字:静态 数据 获取 | 更新日期: 2023-09-27 18:27:15

我在当前应用程序中遇到以下问题。(类示例应理解为实体框架实体类。)

假设您有一个静态类,其中包含一些属性,这些属性在应用程序范围内用作各种Get/Set属性的示例。

每次请求此属性时都会调用属性的Get,对于某些控件的数据绑定,这种情况可能会在每次重新绘制(布局刷新)控件时发生。

现在我面临的问题是,可能会出现这样的情况,我希望打开两个具有不同"静态"值的窗口,实现这种情况的最佳方法是什么?

这里的一些代码可能会让事情更容易理解:

静态类,包含查询中使用的属性:

public static class Core
{
    public string IdLang { get; set; }
    public string IdCompany { get; set; }
}

在属性名称的获取/设置中使用Core.IdLang的类:

public class Car
{
    private string _name;
    public string Name
    {
        get
        {
            _name = (from x in LanguageTables
                    where x.IdLang == Core.IdLang
                    select x.Text).FirstOrDefault();
            return _name;
        }
        set
        {
            if (value == _name)
                return;
            var languageTable = (from x in LanguageTables
                                where x.IdLang == Core.IdLang
                                select x).FirstOrDefault();
            if (languageTable == null)
            {
                languageTable = new LanguageTable();
                languageTable.IdLang = Core.IdLang;
            }
            languageTable.Text = _name;
        }
    }
}

现在,假设您在两个不同的窗口中有两个DataGrids,并希望用两种不同的语言绑定一个汽车列表。

我正在做以下操作(仅针对1个网格和窗口的示例):

public class Window1 : Window
{
    List<Car> Cars;
    public Window1()
    {
        InitializeComponents();
        Core.IdLang = "DE";
        Cars = new List<Car>();            
        //fetch data from Database, and populate the List<Car>
        Grid1.ItemsSource = from x in Cars
                            select x;
    }
}

现在只需要考虑复制并粘贴上面的代码(Window1),并有第二个窗口,希望显示所有带有英文名称的汽车,所以我更改了以下代码:

Core.IdLang = "DE";

Core.IdLang = "EN";

我以为一切都会好起来的,但你以后调用Core.IdLang的任何Window现在都有这个值,一旦在任何一个Window上调用了Get/Set,你只会用这种语言接收或更改它,而在不同的窗口之间没有区别。

在实际应用程序中,Core类将由大约6个(或更多)属性组成,这些属性在50多个类中使用,这些类都至少有一个属性具有与Car.Name示例相同的获取/设置代码。

这些类中的任何一个都可以用于所提供的场景,在该场景中,我希望将英语和德语数据并排显示以进行比较。

正在获取具有不同静态值的数据

基于你想要不同的值,我会问:"你为什么一开始就强制一个静态类?"。大多数时候,在处理实体框架时,您可以使用T4生成器为您制作POCO(普通旧类对象),并与它们相关。然而,如果你想对不同语言的属性进行二级显式持有,为什么不保留顶部定义的"Car"对象,而是删除Core Linq语句呢?

除了用户输入了错误的值之外,我并没有从这个例子中了解到这对你来说是什么。如果由于数据库外键约束而必须单独添加验证方法,则可以始终单独添加该方法。但是,为什么不限制用户可以先用组合框或其他选项进行选择的集合呢?然后你就有了一个蓝图,你可以保留它,以便在不同的情况下重用,甚至可以把它放在构造函数中。我下面的例子非常明确,但你可以把我的逻辑放在其他事件方法中。我试图保持属性get和set非常基本,并在其他部分进行验证。这样一来,他们的IMHO就更容易打字,也就不会对通行证和他们的身份产生混淆

编辑8-11-13以更具体的

// I am the generated POCO form the Entity Model
public class Car
{
    public string IdLang { get; set; }
    public string IdCompany { get; set; }
}
// I am a class for just 'get' methods or update methods potentially
public class GetData
{
     // I am returning a single Entity of 'Car' type based on predicate
     public Car returnSpecificCar(string aLanguage)
    {
        using (EntityName e = new EntityName())
        {
            // I like lambda methods better due to less lines
            return e.Car.FirstOrDefault(n => n.Language == aLanguage);
            // Similar method in Linq style
            // return (from c in e.Car where c.Language == aLanguage
            // select c).FirstOrDefault();
        }
    }
    // I return all cars
    public List<Car> returnAllCars()
    {
        using (EntityName e = new EntityName())
        {
            return e.Car.ToList();
        }
    }
}
// Simple console example
class Program
{
    static void Main(string[] arts)
    {
        GetData d = new GetData();
        var cars = d.returnEntites();
        var specCar1 = d.returnSpecificCar("EN");
        var specCar2 = d.returnSpecificCar("DE");
        string ln = "-----All cars----" + Environment.NewLine;
        cars.ForEach(c => ln += c.CarId + "'t" + c.CarName + Environment.NewLine);
        ln += Environment.NewLine + Environment.NewLine + "----Specific Car1 -----" + Environment.NewLine;
        ln += specCar1.CarID + "'t" + specCar1.CarName+ Environment.NewLine;
        ln += Environment.NewLine + Environment.NewLine + "----Specific Car2 -----" + Environment.NewLine;
        ln += specCar2.CarID + "'t" + specCar2.CarName + Environment.NewLine;
        Console.WriteLine(ln);
        Console.ReadLine();
    }
}

现在,在我的例子中,关键是我选择了给所有的车或特定的车。你可以很容易地将返回值更改为List,并返回一个语言是一对多关系的汽车列表,然后过滤它。我只是想展示你可以用非静态类一次Differentially返回一个对象。通常,除非您需要一个与数据库不同的特定条件类的存储库来跟踪数据库之外的事情,并且只针对应用程序,否则不需要制作更多的POCO。如果它们存在于UI的查看平台,比如遵循MVVM模式的ViewModel。但是,只需要用数据库中的内容填充网格,就不需要创建新的类IMHO。您只需要将返回方法保存在一个类中,该类可以在命令中调用,而在命令中更改。

通过上面的例子,如果你想应用于网格,我相信你可以直接进行

GetData d = new GetData();
var items = d.returnEntities();
// Assumes your grid itemname is 'grid'
grid.ItemsSource = items;

这是一个非常脆弱的代码,因为您在Car类中对Core有外部依赖关系。如果你想让所有的类都自动拥有IdLang,那么你应该使用继承来实现它。否则,你可以使用Dependency Injection,并通过Car构造函数将Core作为参数传递。

就我个人而言,我认为拥有Core类根本没有用。您可以将这两个Properties IdLang和Company放入Car中,并通过构造函数对它们进行初始化。