实体框架核心:如何在引用同一个表的一个实体中配置具有两个一对多关系的模型

时间:2016-06-24 09:38:41

标签: c# entity-framework

我想跟踪谁创建了一个实体,以及谁编辑(最后)该实体。因为我想为我的项目中的每个实体执行此操作,所以我在名为EntityBase的基类中执行此操作。

如果我使用相应的ForeignKey属性取消注释EntityBase类中的EditorUser,则Context.Database.EnsureCreated方法将引发以下异常:

InvalidOperationException异常: 附加信息:无法确定在“User.CreatorUser”和“User”之间检测到的一对一关系的子/从属方。要标识关系的子/依赖方,请配置外键属性。

任何人都可以帮我配置模型以满足我的要求吗?

public class EntityBase
{
    public Guid Id { get; set; }
    public Guid CreatorUserId { get; set; }
    [ForeignKey(nameof(CreatorUserId))]
    public User CreatorUser { get; set; }
    public Guid? EditorUserId { get; set; }
    //[ForeignKey(nameof(EditorUserId))]
    //public User EditorUser { get; set; }
}
public class User : EntityBase
{
    public String Name { get; set; }
}
public class House : EntityBase
{
    public String Address { get; set; }
}
class Context : DbContext
{
    public Guid CurrentUserId = new Guid("3de85c1f-3ce1-4342-a582-83d6cc8e308f");

    public DbSet<User> Users { get; set; }
    public DbSet<House> Houses { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlite(@"Data Source = c:\Temp\eftest.db;");
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        foreach (var relationship in modelBuilder.Model.GetEntityTypes().SelectMany(e => e.GetForeignKeys()))
        {
            relationship.DeleteBehavior = DeleteBehavior.Restrict;
        }
        base.OnModelCreating(modelBuilder);
    }

    public override int SaveChanges()
    {
        var changeSet = ChangeTracker.Entries<EntityBase>();
        if (changeSet != null)
        {
            foreach (var entry in changeSet.Where(c => c.State != EntityState.Unchanged))
            {
                switch (entry.State)
                {
                    case EntityState.Added:
                        entry.Entity.CreatorUserId = CurrentUserId;
                        break;
                    default:
                        entry.Entity.EditorUserId = CurrentUserId;
                        break;
                }
            }
        }
        return base.SaveChanges();
    }
}

1 个答案:

答案 0 :(得分:1)

好吧,基本上CreatorUser EntityBase User来自EntityBaseEntityBasepublic class CenteringHorizontalScrollView extends HorizontalScrollView implements View.OnTouchListener { private static final int SWIPE_PAGE_ON_FACTOR = 5; View targetLeft, targetRight; CircleImageView leftImage, rightImage; private Context mContext; private int mActiveItem; private float mPrevScrollX; private int mItemWidth = 250;// or whatever your item width is. private int centreItemWidth = 350; private final int LEFT = 1; private final int RIGHT = 2; private final int NA = 0; private final int emptyView = 2; private static String TAG = CenteringHorizontalScrollView.class.getSimpleName(); public CenteringHorizontalScrollView(Context context, AttributeSet attrs) { super(context, attrs); mContext = context; setOnTouchListener(this); } @Override public boolean onTouch(View v, MotionEvent event) { int x = (int) event.getRawX(); boolean handled = false; switch (event.getAction()) { case MotionEvent.ACTION_DOWN: mPrevScrollX = x; break; case MotionEvent.ACTION_MOVE: break; case MotionEvent.ACTION_UP: int minFactor = mItemWidth / SWIPE_PAGE_ON_FACTOR; if ((mPrevScrollX - (float) x) > minFactor) { if (mActiveItem < getMaxItemCount() - 1 - emptyView) { setCurrentItem(mActiveItem + 1); CommonConstant.currentChildIdx = (mActiveItem - emptyView); } } else if (((float) x - mPrevScrollX) > minFactor) { if (mActiveItem > 0 + emptyView) { setCurrentItem(mActiveItem - 1); CommonConstant.currentChildIdx = (mActiveItem - emptyView); } } scrollToActiveItem(NA); handled = true; break; } return handled; } private int getMaxItemCount() { return ((LinearLayout) getChildAt(0)).getChildCount(); } private LinearLayout getLinearLayout() { return (LinearLayout) getChildAt(0); } private void setCurrentItem(int cur) { if (cur < 0 + emptyView) { mActiveItem = 2; } else if (cur > getMaxItemCount() - 1 - emptyView) { mActiveItem = getMaxItemCount() - 1 - emptyView; } else { mActiveItem = cur; } } /** * Scrolls the list view to the currently active child. */ private void scrollToActiveItem(int direction) { int maxItemCount = getMaxItemCount(); if (maxItemCount == 0) { return; } int targetItem = Math.min(maxItemCount - 1, mActiveItem); targetItem = Math.max(0, targetItem); setCurrentItem(targetItem); targetItem = mActiveItem; // Scroll so that the target child is centered View targetView = getLinearLayout().getChildAt(targetItem); LinearLayout centerLayout = (LinearLayout) targetView; ImageView centerImage = (ImageView) centerLayout.getChildAt(0); centerImage.setBackground(mContext.getResources().getDrawable(R.drawable.rectangle_background)); //get the image to left of the centered image if ((targetItem - 1) >= 0) { targetLeft = getLinearLayout().getChildAt(targetItem - 1); LinearLayout ll = (LinearLayout) targetLeft; leftImage = (CircleImageView) ll.getChildAt(0); centerImage.setBackground(null); } //get the image to right of the centered image if ((targetItem + 1) < maxItemCount) { targetRight = getLinearLayout().getChildAt(targetItem + 1); LinearLayout ll = (LinearLayout) targetRight; rightImage = (CircleImageView) ll.getChildAt(0); centerImage.setBackground(null); } int targetLeftx = centerLayout.getLeft(); int childWidth = centerLayout.getRight() - targetLeftx; int width = getWidth() - getPaddingLeft() - getPaddingRight(); int targetScroll = targetLeftx - ((width - childWidth) / 2); super.smoothScrollTo(targetScroll, 0); } /** * Sets the current item and centers it. * * @param currentItem The new current item. */ public void setCurrentItemAndCenter(int currentItem) { setCurrentItem(currentItem + emptyView); scrollToActiveItem(NA); } } 。所以它有点像鸡与蛋的问题。 您可以为Parent创建另一个用户实体,并将其添加到 private void initScrollView() { tools_top_scroll = (CenteringHorizontalScrollView) getActivity().findViewById(R.id.horizontalScrollView); rl = (LinearLayout) getActivity().findViewById(R.id.tools_top); addEmptyChildView(); addEmptyChildView(); for (int i = 0; i < 5; i++) { setInnerChildView(getChildren().get(i)); } addEmptyChildView(); addEmptyChildView(); tools_top_scroll.post(new Runnable() { @Override public void run() { tools_top_scroll.setCurrentItemAndCenter(CommonConstant.currentChildIdx); } }); } private void setInnerChildView(ChildR childR) { View view = LayoutInflater.from(getActivity()).inflate(R.layout.item_head_name, null); ImageView child_img = (ImageView) view.findViewById(R.id.child_img); TextView child_name = (TextView) view.findViewById(R.id.child_name); Log.i(TAG, "child name:" + childR.getChild().getC_name()); child_name.setText(childR.getChild().getC_name()); rl.addView(view); } private void addEmptyChildView() { View view = LayoutInflater.from(getActivity()).inflate(R.layout.item_head_name, null); view.setVisibility(View.INVISIBLE); rl.addView(view); }