Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 泛化一个类以处理多个类型_C# - Fatal编程技术网

C# 泛化一个类以处理多个类型

C# 泛化一个类以处理多个类型,c#,C#,我的数据库模式中有一系列大约30个查找表,它们都具有相同的布局(我更愿意将它们作为单独的表而不是一个查找表),因此我的Linq2SQL上下文中有30个实体用于这些查找表 我有一个标准类,用于这30个实体的CRUD操作,例如: public class ExampleAttributes : IAttributeList { #region IAttributeList Members public bool AddItem(string Item, int SortOrder)

我的数据库模式中有一系列大约30个查找表,它们都具有相同的布局(我更愿意将它们作为单独的表而不是一个查找表),因此我的Linq2SQL上下文中有30个实体用于这些查找表

我有一个标准类,用于这30个实体的CRUD操作,例如:

public class ExampleAttributes : IAttributeList
{
    #region IAttributeList Members

    public bool AddItem(string Item, int SortOrder)
    {
        MyDataContext context = ContextHelper.GetContext();
        ExampleAttribute a = new ExampleAttribute();
        a.Name = Item;
        a.SortOrder = SortOrder;
        context.ExampleAttributes.InsertOnSubmit(a);

        try
        {
            context.SubmitChanges();
            return true;
        }
        catch
        {
            return false;
        }
    }

    public bool DeleteItem(int Id)
    {
        MyDataContext context = ContextHelper.GetContext();

        ExampleAttribute a = (from m in context.ExampleAttributes
                            where m.Id == Id
                            select m).FirstOrDefault();

        if (a == null)
            return true;

        // Make sure nothing is using it
        int Count = (from m in context.Businesses
                             where m.ExampleAttributeId == a.Id
                             select m).Count();

        if (Count > 0)
            return false;

        // Delete the item
        context.ExampleAttributes.DeleteOnSubmit(a);

        try
        {
            context.SubmitChanges();
            return true;
        }
        catch
        {
            return false;
        }
    }

    public bool UpdateItem(int Id, string Item, int SortOrder)
    {
        MyDataContext context = ContextHelper.GetContext();

        ExampleAttribute a = (from m in context.ExampleAttributes
                            where m.Id == Id
                            select m).FirstOrDefault();

        a.Name = Item;
        a.SortOrder = SortOrder;

        try
        {
            context.SubmitChanges();
            return true;
        }
        catch
        {
            return false;
        }
    }

    public String GetItem(int Id)
    {
        MyDataContext context = ContextHelper.GetContext();
        var Attribute = (from a in context.ExampleAttributes
                         where a.Id == Id
                         select a).FirstOrDefault();

        return Attribute.Name;
    }

    public Dictionary<int, string> GetItems()
    {
        Dictionary<int, string> Attributes = new Dictionary<int, string>();

        MyDataContext context = ContextHelper.GetContext();
        context.ObjectTrackingEnabled = false;

        Attributes = (from o in context.ExampleAttributes orderby o.Name select new { o.Id, o.Name }).AsEnumerable().ToDictionary(k => k.Id, v => v.Name);

        return Attributes;
    }

    #endregion
}
公共类示例属性:IAttributeList
{
#地区论坛成员
公共bool AddItem(字符串项,整数排序器)
{
MyDataContext=ContextHelper.GetContext();
ExampleAttribute=新的ExampleAttribute();
a、 名称=项目;
a、 SortOrder=SortOrder;
context.ExampleAttributes.InsertOnSubmit(a);
尝试
{
context.SubmitChanges();
返回true;
}
抓住
{
返回false;
}
}
公共布尔删除项(内部Id)
{
MyDataContext=ContextHelper.GetContext();
ExampleAttribute=(来自context.ExampleAttributes中的m
其中m.Id==Id
选择m).FirstOrDefault();
如果(a==null)
返回true;
//确保没有任何东西在使用它
int Count=(来自context.business中的m)
其中m.ExampleAttributeId==a.Id
选择m.Count();
如果(计数>0)
返回false;
//删除该项目
context.ExampleAttributes.DeleteOnSubmit(a);
尝试
{
context.SubmitChanges();
返回true;
}
抓住
{
返回false;
}
}
公共bool UpdateItem(int-Id、字符串项、int-SortOrder)
{
MyDataContext=ContextHelper.GetContext();
ExampleAttribute=(来自context.ExampleAttributes中的m
其中m.Id==Id
选择m).FirstOrDefault();
a、 名称=项目;
a、 SortOrder=SortOrder;
尝试
{
context.SubmitChanges();
返回true;
}
抓住
{
返回false;
}
}
公共字符串GetItem(int Id)
{
MyDataContext=ContextHelper.GetContext();
var Attribute=(来自context.ExampleAttributes中的
其中a.Id==Id
选择一个.FirstOrDefault();
返回属性.Name;
}
公共字典GetItems()
{
字典属性=新字典();
MyDataContext=ContextHelper.GetContext();
context.ObjectTrackingEnabled=false;
Attributes=(从context.ExampleAttributes orderby o.Name选择new{o.Id,o.Name}).AsEnumerable().ToDictionary(k=>k.Id,v=>v.Name);
返回属性;
}
#端区
}
我可以将这个类复制30次,对每个查找实体进行非常小的更改,但这似乎有点混乱-所以这个类可以被泛化,以便我也可以传递我想要的类型,并让它在内部处理linq查询中的类型差异吗?这样的话,我有一个类要添加,一个类要修复bug等等——看起来应该这样做

更新:

下面的Andrews回答为我提供了一个选项,我在思考这个问题时确实在考虑这个选项(输入),但我需要更多关于如何泛化linq查询的说明。有人能澄清这一点吗

干杯


Moo

有几件事你可以试试

一种是定义一个接口,该接口具有三十个实体类共享的所有相关字段。然后,您可以让每个实体类实现这个接口(我们称它为
IMyEntity

public partial class EntityNumber1 : IMyEntity
{
}
对于每个实体(其中
EntityNumber1
是其中一个实体类的名称)。当然,这仍然是30个不同的定义,但是您的CRUD操作类可以在
IMyEntity
上操作,而不必每次都编写一个新的类

第二种方法是简单地将CRUD操作类泛化,如您所建议的:

public class ExampleAttributes<T> : IAttributeList
{
    ...
公共类示例属性:IAttributeList
{
...
允许您使用T作为操作的类型。当然,与第一个方法结合使用可能会更容易,因为您仍然需要检查属性的存在,并将实体强制转换为适当的类型或接口

编辑:

要检查实体上是否存在适当的属性,可能需要使用反射方法

typeof(T).GetProperties().OfType<PropertyInfo>().Count<PropertyInfo>(pi => pi.Name == "MyPropertyName" && pi.GetGetMethod().ReturnType == typeof(TypeIWant)) > 0
typeof(T).GetProperties().OfType().Count(pi=>pi.Name==“MyPropertyName”&&pi.getMethod().ReturnType==typeof(TypeIWant))>0

当然,将
TypeIWant
替换为您期望的属性类型,并将
MyPropertyName
替换为您正在检查的属性名称。

向指定类型的构造函数添加一个参数。然后您可以在内部使用它。一个类,可能在构造函数。

对于泛化LINQ查询,最大的问题是您的DataContext具有基于类型的集合。有几种方法可以避免这种情况。您可以尝试使用反射来访问它,但这将需要相当多的黑客攻击,并且几乎会破坏LINQ to SQL提供的所有效率。

最简单的方法似乎是使用Dynamic LINQ。我没有亲自使用过它,但它似乎应该支持它。您可以在此线程中找到更多信息: 等等
也许其他人可以提供更多信息?

这不一定是ans