我有三个类定义如下:
public class Base
{
public int Id { get; set; }
}
public class Bar : Base { ... }
public class Foo : Base
{
public int? ParentId { get; set; }
public Base Parent { get; set; }
public int? FooParentId { get; set; }
public Foo FooParent { get; set; }
public int? BarParentId { get; set; }
public Bar BarParent { get; set; }
public Foo(Foo parent)
{
FooParent = parent;
FooParentId = parent.Id;
Parent = FooParent; // Now changes to Parent are reflected on FooParent
ParentId = FooParentId; // Changes to ParentId are not reflected because it is a value type.
}
public Foo(Bar parent)
{
// Same implementation as ctor(Foo parent);
}
}
我尝试做的是Parent
引用FooParent
或BarParent
(我认为相当简单),然后ParentId
引用{{ 1}}或FooParentId
。使BarParentId
成为引用类型的最理智的方法是什么?
答案here提到整数的装箱/拆箱有很多与之相关的问题 这真的是一个糟糕的解决方案吗?
修改
我应该提到ParentId
和Foo
是实体框架表。 Bar
是一个对象,可以是一个表或另一个表的子节点,对于Entity Framework代码 - 首先要正确生成表,必须定义Foo
和FooParent
。此外,BarParent
可能不会在其getter中引用ParentId
。实体框架也应该归咎于此。致电Parent
时,实体框架Reinserts Existing Objects。所有非空的父母都会被重新插入。
答案 0 :(得分:1)
如果您的双手被EF绑定,您可以使用委托来根据构造函数中传递的类型传播ParentId
的更改。我不知道EF是否会抱怨这个。
例如,使用Action<T>
委托,我们可以将更改转发至ParentId
到相应的[Foo|Bar]ParentId
:
public class Base
{
public int Id { get; set; }
}
public class Bar : Base { }
public class Foo : Base
{
private int? _parentId;
public int? ParentId {
get{ return _parentId; }
set{
_parentId = value;
if( OnParentChangeAction != null ) {
OnParentChangeAction( _parentId );
}
}
}
public Base Parent { get; set; }
public int? FooParentId { get; set; }
public Foo FooParent { get; set; }
public int? BarParentId { get; set; }
public Bar BarParent { get; set; }
private Action<int?> OnParentChangeAction{ get; set; }
public Foo(Foo parent)
{
FooParent = parent;
FooParentId = parent.Id;
Parent = FooParent;
ParentId = FooParentId;
OnParentChangeAction = newParentId => FooParentId = newParentId;
}
public Foo(Bar parent)
{
BarParent = parent;
BarParentId = parent.Id;
Parent = BarParent;
ParentId = BarParentId;
OnParentChangeAction = newParentId => BarParentId = newParentId;
}
}
答案 1 :(得分:0)
由于您已经引用了父对象,因此可以使用属性获取其Id:
public int? ParentId
{
get
{
return Parent != null ? Parent.Id : null;
}
}
答案 2 :(得分:0)
您可以为get
和set
属性的FooParentId
和BarParentId
访问者添加逻辑,但同意@Servy这是一个糟糕的设计。
原因甚至不仅是ID-s和引用对象。我不明白为什么你需要同时拥有BarParent和FooParent,只有1个IParent
类型的属性,然后使用该接口提供的方法与它进行通信,利用继承和多态的所有好处。