Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.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# DDD中的空实体_C#_Null_Domain Driven Design_Nullable - Fatal编程技术网

C# DDD中的空实体

C# DDD中的空实体,c#,null,domain-driven-design,nullable,C#,Null,Domain Driven Design,Nullable,以产品实体或集合为例,该实体或集合引用了另一个名为类别的实体。在发生像CategorizeProduct这样的域事件之前,类别的状态为空。为了在C#中表示这一点,我必须使用NULL。我不能在C#中使用Nullable,因为它只能用于值类型 在DDD中使用NULL是否为反模式?建议的一些解决方案是:(1)使用或(2)使用a代替单个实体 也许是一个选项,但是否有不同的方法来处理DDD中的空实体状态?我理解您的担忧-NULL可能表示尚未加载类别,或者可能表示尚未分配类别 一个选项是添加一个可为空的属性

产品实体或集合为例,该实体或集合引用了另一个名为类别的实体。在发生像CategorizeProduct这样的域事件之前,类别的状态为空。为了在C#中表示这一点,我必须使用
NULL
。我不能在C#中使用
Nullable
,因为它只能用于值类型

在DDD中使用
NULL
是否为反模式?建议的一些解决方案是:(1)使用
(2)使用a代替单个实体


也许
是一个选项,但是否有不同的方法来处理DDD中的空实体状态?

我理解您的担忧-NULL可能表示尚未加载类别,或者可能表示尚未分配类别

一个选项是添加一个可为空的属性CategoryId,其中包含已分配类别的ID。如果分配了类别,则始终填写ID,否则为空。这意味着,如果填写了CategoryID且Category为空,则分配了一个类别,但未加载该类别

如果您使用实体框架来加载或持久化您的域,那么这种方法自然适合

 public class Product
 {
      public Product()
      {
          // validate entity 
      }

      public int? CategoryId { get; private set; }
      public Category Category { get; private set; } 
 }

我理解您的担忧-NULL可能表示尚未加载类别,也可能表示尚未分配类别

一个选项是添加一个可为空的属性CategoryId,其中包含已分配类别的ID。如果分配了类别,则始终填写ID,否则为空。这意味着,如果填写了CategoryID且Category为空,则分配了一个类别,但未加载该类别

如果您使用实体框架来加载或持久化您的域,那么这种方法自然适合

 public class Product
 {
      public Product()
      {
          // validate entity 
      }

      public int? CategoryId { get; private set; }
      public Category Category { get; private set; } 
 }

我理解您的担忧-NULL可能表示尚未加载类别,也可能表示尚未分配类别

一个选项是添加一个可为空的属性CategoryId,其中包含已分配类别的ID。如果分配了类别,则始终填写ID,否则为空。这意味着,如果填写了CategoryID且Category为空,则分配了一个类别,但未加载该类别

如果您使用实体框架来加载或持久化您的域,那么这种方法自然适合

 public class Product
 {
      public Product()
      {
          // validate entity 
      }

      public int? CategoryId { get; private set; }
      public Category Category { get; private set; } 
 }

我理解您的担忧-NULL可能表示尚未加载类别,也可能表示尚未分配类别

一个选项是添加一个可为空的属性CategoryId,其中包含已分配类别的ID。如果分配了类别,则始终填写ID,否则为空。这意味着,如果填写了CategoryID且Category为空,则分配了一个类别,但未加载该类别

如果您使用实体框架来加载或持久化您的域,那么这种方法自然适合

 public class Product
 {
      public Product()
      {
          // validate entity 
      }

      public int? CategoryId { get; private set; }
      public Category Category { get; private set; } 
 }

对于这些类型的东西,您可以使用。例如,可以将
String.Empty
属性作为一个简单的例子

如果
null
对象的某些方法应该具有不同的行为,则可以将其作为一个私有内部类,该类派生自
Category
,并重写特定的行为

对于您的
类别

public class Category
{
    private class UnassignedCategory : Category
    {
        public UnassignedCategory() : base("") { }
    }

    private static readonly UnassignedCategory _unassigned = new UnassignedCategory();

    public static Category Unassigned 
    { 
        get { return _unassigned; }
    }

    public Category(string name) 
    {
        this.Name = name;
    }

    public string Name { get; private set; }

    public bool IsAssigned 
    {
        get { return ReferenceEquals(this, _unassigned); }
    }
}
请注意,在上面的示例中,由于
Category
上没有默认的无参数构造函数,并且无法更改
Name
属性的值,因此实际上不需要子类,我们可以简单地使用静态
Category
实例

用法:

public class Product
{
    public Product()
    {
        Category = Category.Unassigned;
        // other stuff
    }

    // other stuff.

    public void AssignCategory(Category category) 
    {
        // Any associated logic.
        Category = category;
    }
    public Category Category { get; private set; } 
}
如果您正在从数据库中保存和加载
null
(即未分配)类别,您可能希望在此主题上使用一个变体,带有“未分配”的显式(不可变)id/属性,该id/属性与其他
类别
属性一起保存,并在
IsAssigned
检查中使用

可行的替代方案

一个完全可行的替代方法是使用
null
引用继续做您现在正在做的事情。如果需要,您可以添加一些扩展方法,使您的生活更轻松

public static MyCategoryExtensions
{
    public static bool IsNullOrEmpty(this Category category) 
    {
        return category == null || string.IsNullOrEmpty(category.Name);
    }
    public static Category EmptyIfNull(this Category category) 
    {
        return category ?? new Category("");
    }
    public static Category DefaultIfNullOrEmpty(this Category category) 
    {
        return category.IsNullOrEmpty() 
            ? new Category(Category.DefaultName)
            : category;
    }
}

对于这些类型的东西,您可以使用。例如,可以将
String.Empty
属性作为一个简单的例子

如果
null
对象的某些方法应该具有不同的行为,则可以将其作为一个私有内部类,该类派生自
Category
,并重写特定的行为

对于您的
类别

public class Category
{
    private class UnassignedCategory : Category
    {
        public UnassignedCategory() : base("") { }
    }

    private static readonly UnassignedCategory _unassigned = new UnassignedCategory();

    public static Category Unassigned 
    { 
        get { return _unassigned; }
    }

    public Category(string name) 
    {
        this.Name = name;
    }

    public string Name { get; private set; }

    public bool IsAssigned 
    {
        get { return ReferenceEquals(this, _unassigned); }
    }
}
请注意,在上面的示例中,由于
Category
上没有默认的无参数构造函数,并且无法更改
Name
属性的值,因此实际上不需要子类,我们可以简单地使用静态
Category
实例

用法:

public class Product
{
    public Product()
    {
        Category = Category.Unassigned;
        // other stuff
    }

    // other stuff.

    public void AssignCategory(Category category) 
    {
        // Any associated logic.
        Category = category;
    }
    public Category Category { get; private set; } 
}
如果您正在从数据库中保存和加载
null
(即未分配)类别,您可能希望在此主题上使用一个变体,带有“未分配”的显式(不可变)id/属性,该id/属性与其他
类别
属性一起保存,并在
IsAssigned
检查中使用

可行的替代方案

一个完全可行的替代方法是使用
null
引用继续做您现在正在做的事情。如果需要,您可以添加一些扩展方法,使您的生活更轻松

public static MyCategoryExtensions
{
    public static bool IsNullOrEmpty(this Category category) 
    {
        return category == null || string.IsNullOrEmpty(category.Name);
    }
    public static Category EmptyIfNull(this Category category) 
    {
        return category ?? new Category("");
    }
    public static Category DefaultIfNullOrEmpty(this Category category) 
    {
        return category.IsNullOrEmpty() 
            ? new Category(Category.DefaultName)
            : category;
    }
}

对于这些类型的东西,您可以使用。例如,可以将
String.Empty
属性作为一个简单的例子

如果
null
对象的某些方法应该具有不同的行为,则可以将其作为一个私有内部类,该类派生自
Category
,并重写特定的行为

对于您的
类别

public class Category
{
    private class UnassignedCategory : Category
    {
        public UnassignedCategory() : base("") { }
    }

    private static readonly UnassignedCategory _unassigned = new UnassignedCategory();

    public static Category Unassigned 
    { 
        get { return _unassigned; }
    }

    public Category(string name) 
    {
        this.Name = name;
    }

    public string Name { get; private set; }

    public bool IsAssigned 
    {
        get { return ReferenceEquals(this, _unassigned); }
    }
}
请注意,在上面的示例中,由于
Category
上没有默认的无参数构造函数,并且无法更改
Name
属性的值,因此实际上不需要子类,我们可以简单地使用静态
Category
实例

用法: