在C#中使用泛型进行条件比较

在C#中使用泛型进行条件比较,c#,asp.net,sql-server,entity-framework,C#,Asp.net,Sql Server,Entity Framework,在我的场景中,我有两种类型的对象。一个计划和一个层级。每个层共享某些值,而层有3个附加值(速率、最小值和最大值) 我想创建一个通用方法,根据以下条件有条件地评估是否可以将新对象写入数据库: 创建: A层:((o1.Rate!=o2.Rate)| |((o1.Start!=o2.Start)&&&(o1.End!=o2.End))&&(MinVal&&MaxVal) 层或计划:(o1.Name!=o2.Name) 层或计划:只有一个可以有(Active==true),其余必须为false 有可能为

在我的场景中,我有两种类型的对象。一个计划和一个层级。每个层共享某些值,而层有3个附加值(速率、最小值和最大值)

我想创建一个通用方法,根据以下条件有条件地评估是否可以将新对象写入数据库:

创建:

  • A层:
    ((o1.Rate!=o2.Rate)| |((o1.Start!=o2.Start)&&&(o1.End!=o2.End))&&(MinVal&&MaxVal)
  • 层或计划:
    (o1.Name!=o2.Name)
  • 层或计划:只有一个可以有
    (Active==true)
    ,其余必须为false
  • 有可能为这样的东西创建一个通用方法吗?如果有,有这样的例子吗?或者有人有什么建议吗

    谢谢

    更多信息:
    因此,我有一个对象列表,在将新创建的对象写入数据库之前,我需要将其与数据库中的其他对象进行比较。

    为了使其工作,通用方法(或类型)需要一个约束,使其能够理解您列出的所有单个属性(
    费率
    日期
    最小值
    最大值
    开始
    ,和
    结束

    如果您担心的所有类型都来自同一个基类或接口,那么您不需要泛型,只需构建一个接受该基类的两个参数的方法即可


    但是,如果它们不这样做,泛型可能也不适合这里-但是,还有另一种选择。您可以使用
    动态
    使用运行时绑定有效地使用这些属性。请注意,如果您传递的类型参数没有这些属性,它将在运行时失败。

    可能是这样的:

    // I'm making up the types here; modify to match your actual types
    public interface IMyObject {
        public int Rate { get; set; }
        public DateTime Date { get; set; }
        public int MinVal { get; set; }
        public int MaxVal { get; set; }
        public DateTime Start { get; set; }
        public DateTime End { get; set; }
    }
    
    public static class MyObjectFactory {
        public static T Create<T>(int rate, DateTime date, /* etc.. */) 
                where T : IMyObject, new() {
    
            if (/* tests */) {
                throw new MyObjectException("Constraint violated ...");
            }             
    
            T obj = new T();
    
            obj.Rate = rate;
            obj.Date = date;
            // etc ....
    
            return obj;
        }
    }
    
    //我在这里创建类型;修改以匹配您的实际类型
    公共接口IMyObject{
    公共整数速率{get;set;}
    公共日期时间日期{get;set;}
    公共int MinVal{get;set;}
    公共int MaxVal{get;set;}
    公共日期时间开始{get;set;}
    公共日期时间结束{get;set;}
    }
    公共静态类MyObject工厂{
    公共静态T创建(整数速率、日期时间日期、/*等…*/)
    其中T:IMyObject,new(){
    如果(/*测试*/){
    抛出新的MyObjectException(“违反约束…”);
    }             
    T obj=新的T();
    目标费率=费率;
    对象日期=日期;
    //等等。。。。
    返回obj;
    }
    }
    
    然后你会这样使用它:

    public class SomeMyObject : IMyObject {
        // implementation omitted for brevity ...
    }
    
    // somewhere:
    SomeMyObject obj = MyObjectFactory.Create<SomeMyObject>(rate, date, /* etc. */);
    
    公共类SomeMyObject:IMyObject{
    //为简洁起见,省略了实现。。。
    }
    //某处:
    SomeMyObject obj=MyObjectFactory.Create(rate、date、/*等*/);
    

    这就是你想要的吗?

    你的选择基本上是:

  • 将公共继承基础对象与这些道具一起使用
  • 实现与这些道具的接口
  • 如果对象确实不相关,或者在运行时只知道比较的字段值,则使用反射获取值并进行比较

  • 里德在下面提到了动态对象——这可能行得通,我不得不相信他的答案,但其中包括了动态需求。

    我真的不确定问题是什么……但如果所有这些都是某种“预先检查”在数据库中创建对象之前,我通常求助于数据库中的存储过程,该过程采用所有相关参数进行创建并返回主键,或者在失败时返回错误代码…如果成功,则使用主键从数据库中加载创建的对象

    在这种比较中,数据库通常是非常有效的——如果我需要并行运行程序的多个实例和/或独立于不同的程序创建对象,数据库解决方案会处理它

    编辑-根据评论/请求:
    我通常与Oracle合作,因此手头没有任何SQL Server存储过程……但这些链接应该提供一些见解:


    似乎不太合适,除非我在你的问题中遗漏了一些基本上简单的东西。你想制作一个方法来比较其中两个对象,还是创建其中两个对象?我真的不明白你在这里想要实现什么……这听起来是一个有趣的问题,但我(可能还有其他人)你很难分辨你在问什么,你的例子也很难理解。能否添加一个你希望客户端代码看起来像什么的示例?我将比较一个已经创建的对象和一个我想创建的对象。你如何比较存在的东西和不存在的东西?好吧,如果你看我编辑的帖子,y你会看到我提到,虽然计划和层只共享4个值,而层有3个附加值。要进一步添加,这是使用实体框架-创建的对象是TblPlan/TblTier的形式,因此它不是从基类继承的。所以你是说我可以为SQL server编写一个存储过程,它可以与与用户确认,让他们知道他们的值已经存在?基本上是-存储过程会传回新的主键(=成功创建对象)、错误代码(=由于存在对象而失败)/或者已经存在的“重复对象”的现有主键…然后,您的程序以您想要的任何方式将其传回给用户…您知道我可以使用的任何此类示例吗?我对存储过程了解不多。我通常与Oracle合作,但请参见上面的编辑-链接应为您提供SQL Server的良好起点