0

我当前的应用程序中存在以下问题。(类示例应理解为 Entity Framework 实体类。)

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

每次您请求此属性时都会调用该属性的 Get,并且每次对控件进行重绘(布局刷新)时,都会对某些控件进行数据绑定。

现在我面临的问题是,我希望打开 2 个具有不同“静态”值的窗口,实现这种情况的最佳方法是什么?

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

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

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

在属性名称的 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;
        }
    }
}

现在让我们假设您在 2 个不同的窗口中有 2 个 DataGrid,并且想要绑定具有两种不同语言的汽车列表。

我正在执行以下操作(仅适用于 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 现在都具有此值,并且一旦在任一窗口上调用 Get/Set,您将只能以这种语言接收或更改它,并且在窗口之间没有区别。

在现实生活中的应用程序中,Core 类将包含大约 6 个(或更多)属性,这些属性在 50 多个类中使用,这些类都具有至少一个具有相同 get/set 代码的属性,正如您在 Car.Name 示例中看到的那样。

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

4

2 回答 2

0

基于您想要具有不同的值,我会问:“为什么您首先要强制使用静态类?”。大多数情况下,在处理实体框架时,您可以获得 T4 生成器来为您制作 POCO(普通旧类对象)并且您与它们相关联。但是,如果您想为不同语言创建二级显式属性,为什么不保留顶部定义的“汽车”对象,而是删除 Core Linq 语句?

除非用户输入错误的值,否则我没有从示例中得到什么是为您实现的。如果由于数据库外键约束而必须单独添加验证方法,则始终可以单独添加。但是,为什么不首先限制用户可以使用组合框或其他方式选择的集合呢?然后你就有了一个蓝图,你可以保留以在不同情况下重复使用,甚至可以将其放入构造函数中。我下面的示例非常明确,但您可以采用我的逻辑并将其放入其他事件方法中。我尝试保持属性获取和设置非常基本,并在其他部分进行验证。这样一来,恕我直言,他们的类型更好,并且传递与他们将是什么的混淆更少。例如:

编辑 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 并返回语言是一对多关系的汽车列表,然后过滤它。我只是想展示你可以使用非静态类一次返回一个对象。通常,除非您需要与数据库不同的某个条件类的存储库来跟踪数据库之外的内容并且仅用于应用程序,否则不需要制作更多的 POCO。如果它们存在于 UI 的查看平台,例如遵循 MVVM 模式的 ViewModel。但是对于只是用数据库中的内容填充网格,没有必要创建一个新的类恕我直言。

通过上面的示例,如果您想应用于网格,我相信您可能会这样做

GetData d = new GetData();

var items = d.returnEntities();

// Assumes your grid itemname is 'grid'
grid.ItemsSource = items;
于 2013-08-09T16:23:59.073 回答
0

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

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

于 2013-08-09T15:49:54.263 回答