Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/265.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.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#_Entity Framework_Oop_Linq To Sql_Domain Driven Design - Fatal编程技术网

C# 获取对象内的所有关联/组合对象(以抽象方式)

C# 获取对象内的所有关联/组合对象(以抽象方式),c#,entity-framework,oop,linq-to-sql,domain-driven-design,C#,Entity Framework,Oop,Linq To Sql,Domain Driven Design,业务: 我有一个支付系统,可以通过GiftCoon、ClubMembershipCard等进行支付。一次支付本身可以有多个支付组件 类: 我有一个付款班。它有支付组件,如GiftCouponPayment、ClubMembershipCardPayment、CashPayment等。每个组件类型都满足一个公共接口IPaymentComponent。我已经使用关于现有类型的知识实现了它 问题 1) 如何以抽象的方式实现此功能–而不知道存在的所有类型是什么?这意味着它需要适用于实现IPaymentC

业务

我有一个支付系统,可以通过GiftCoon、ClubMembershipCard等进行支付。一次支付本身可以有多个支付组件

我有一个付款班。它有支付组件,如GiftCouponPayment、ClubMembershipCardPayment、CashPayment等。每个组件类型都满足一个公共接口IPaymentComponent。我已经使用关于现有类型的知识实现了它

问题

1) 如何以抽象的方式实现此功能–而不知道存在的所有类型是什么?这意味着它需要适用于实现IPaymentComponent接口的所有类型

2) 如果不能在LINQ到SQL中实现它,那么在实体框架中是否可能实现它

3) LINQ to SQL在支付对象内生成GiftCouponPayment实体时是关联/聚合还是合成

注意:我使用LINQtoSQL作为ORM。GiftCouponPayment和Payment是自动生成的类,这些对象由ORM创建。我通过使用分部类为这些类添加了更多功能


注意:在数据库中,每个PaymentComponent(如GiftCouponPayment)都有自己的属性(如CouponValue、CardValue等)。因此,每个层次结构的表将不好。我们需要分开的桌子。这方面有解决办法吗

注意:在此付款之前,数据库中已存在GiftCouponPayment。我们需要使用客户提供的GiftCouponPaymentID来识别GiftCouponPayment对象。我们只需要更新此表中的PaymentID列

泄漏抽象是指任何实现的抽象,旨在降低(或隐藏)复杂性,其中底层细节没有完全隐藏

LINQ到SQL关系图

参考

  • 如何选择继承策略
  • Fluent API样本-
  • C#代码

    public interface IPaymentComponent
    {
         int MyID { get; set; }
         int MyValue { get; set; }
         int GetEffectiveValue();
    }
    
    
    public partial class GiftCouponPayment : IPaymentComponent
    {
        public int MyID
        {
            get 
            { 
                return this.GiftCouponPaymentID; 
            }
            set 
            { 
                this.GiftCouponPaymentID = value; 
            }
        }
    
        public int MyValue
        {
            get 
            { 
                return this.CouponValue; 
            }
            set 
            { 
                this.CouponValue = value; 
            }
        }
    
        public int GetEffectiveValue()
        {
            if (this.CouponNumber < 2000)
            {
                return 0;
            }
            return this.CouponValue;
        }
    }
    
    public partial class Payment
    {
        public List<IPaymentComponent> AllPaymentComponents()
        {
            List<IPaymentComponent> allPayComps = new List<IPaymentComponent>();
    
    
            List<GiftCouponPayment> giftCouponPaymentList = new List<GiftCouponPayment>();
            List<CashPayment> cashPaymentList = new List<CashPayment>();
    
            foreach (GiftCouponPayment g in this.GiftCouponPayments)
            {
                giftCouponPaymentList.Add(g);
                allPayComps.Add(g);
            }
    
            foreach (CashPayment c in this.CashPayments)
            {
                cashPaymentList.Add(c);
                allPayComps.Add(c);
            }
    
            return allPayComps;
    
    
        }
    }
    
    公共接口IPaymentComponent { int MyID{get;set;} int MyValue{get;set;} int GetEffectiveValue(); } 公共部分类礼品付费:IPaymentComponent { 公共整数MyID { 得到 { 返回此.GiftCouponPaymentID; } 设置 { this.GiftCouponPaymentID=值; } } 公共整数MyValue { 得到 { 返回此.CouponValue; } 设置 { this.CouponValue=值; } } public int GetEffectiveValue() { 如果(此.CouponNumber<2000) { 返回0; } 返回此.CouponValue; } } 公共部分类付款 { 公共列表AllPaymentComponents() { List allPayComps=新列表(); List giftCouponPaymentList=新列表(); List cashPaymentList=新列表(); foreach(此.GiftCouponPayments中的giftcouponpaymentg) { 礼品支付清单。添加(g); 所有薪酬加总(g); } foreach(本表中的现金支付c.现金支付) { 现金支付清单。添加(c); 全部薪酬增加(c); } 返回所有PayComps; } }
    您可以尝试使用T型泛型的抽象层或数据访问层,或者至少使方法泛型。

    如果您设计EF模型,您可以在名为payment的基类上使用抽象属性。并继承该类中的所有付款类型:

    付款将具有所有公共属性,并且每个特定类型都可以具有自己的属性

    如果你有这种模式,你可以只查询付款

    这将返回继承付款类型的所有对象:

    
    var allPayments = objectContext.Payments;
    

    我想你可能想从设计上退一步。我听到的是:

    付款由一个或多个组成部分组成,每个组成部分可以是多种类型中的一种

    听起来您需要的是一个
    Payment
    表,然后是一个带有外键关系的
    PaymentComponent
    表,返回到
    Payment
    表。然后,您可以在
    PaymentComponent
    表上为各种支付形式实现继承。

    这里基本上有几个问题:
  • 如何对付款类型进行建模

    假设我们想以经典的OOP方式进行此操作:

    您需要一个基类Payment(或PaymentBase),它是抽象的,并且是从中继承的各种类,例如PaymentInCash、PaymentWithCreditCard等

    另一种方法是向PaymentDetails添加PaymentDetails并创建PaymentDetails的层次结构,如果您选择这样做,则在以下所有要点中使用PaymentDetails替换Payment

    对于使用多种方法的付款,您可以:

    a。在付款项下收集付款明细

    B创建名为AggregatePayment的类型,该类型具有付款列表

  • 如何将付款类型映射到表

    TPT和TPH在这里都有效

    对于TPT使用一个表进行付款,每种付款使用一个表。
    所有继承类型的表PK都应该是基类型表的FK。
    如果您有多个层次结构级别,如果您使用的是EF,则可以在第二个(或任何其他)级别上使用TPT或TPH

    对于TPH使用一个带有鉴别器列(例如PaymentType)的表,并将层次结构中所有实体之间未共享的每一列标记为可空。不要对不同实体中的不同属性使用同一列。在EF中,将每个实体映射到条件PaymentType=(数字在这里)和(colum)的同一个表
    abstract class PaymentProcessor
    {
    }
    
    abstract class PaymentProcessor<TPayment> : PaymentProcessor
        where TPayment : class, Payment
    {
    }
    
    class PaymentInCashProcessor : PaymentProcessor<PaymentInCash>
    {
    }
    
    // Use reflection to find types that inherits from PaymentProcessor<PaymentInCash>
    // create an instance of the type you found
    // then cast the instance to PaymentProcessor<PaymentInCash> to use