Linq to Sql - 如何使用存储库模式更新对象?

有大量的信息,但即使阅读了几个小时和几小时后,我似乎无法按照我想要的方式工作。 我试图通过传入User对象并通常将更改与我从数据库中拉出的User对象进行比较来更新User对象。使用此方法时,我总是得到NotSupportedException:   已尝试附加或   或许,添加一个非新的实体   从另一个装载   DataContext的。这不受支持。 以下是我尝试这样做的方法:
    public void SaveUser(User User)
    {
        using (DataContext dataContext = new DataContext(WebConfigurationManager.ConnectionStrings["database"].ConnectionString))
        {
            // New user
            if (User.UserID == 0)
            {
                dataContext.Users.InsertOnSubmit(User);
            }
            // Existing user
            else
            {
                User dbUser = dataContext.Users.Single(u => u.UserID.Equals(User.UserID));
                Type t = dbUser.GetType();
                foreach (PropertyInfo p in t.GetProperties())
                {
                    if (p.CanWrite & p.GetValue(dbUser, null) != p.GetValue(User, null))
                    {
                        p.SetValue(dbUser, p.GetValue(User, null), null);
                    }
                }
                //dataContext.Refresh(RefreshMode.KeepCurrentValues, dbUser);
            }
            dataContext.SubmitChanges();
        }
    }
我评论过的评论栏也没有注释,但没有任何帮助。 如果我注释掉foreach()循环并添加一行像dbUser.UserName =“Cheese”;它会更新数据库中的用户名。这让我相信它与foreach()循环如何更改导致此失败的dbUser对象有关。 当我调试dbUser对象时,它似乎正确地从作为参数传递的User对象获取所有更改。 我还对乐观并发做了一些阅读,并在数据类型时间戳表中添加了一列,但这似乎也没有任何影响。 我到底错在了什么? 如何通过一般性地检测已更改的内容并正确保留对数据库的更改?     
已邀请:
我的猜测是你有一个外键关系,你试图复制它最初没有加载(因为延迟加载)在复制过程中,它试图加载它,但DataContext已经被处理掉了。 我一直在研究类似的问题。我最终使用AutoMapper处理复制属性。我已将AutoMapper配置为忽略主键字段以及任何关系。就像是:
public void Update(User user)
{
     using (var db = new DataContext(...))
     {
         var userFromDb = db.Users.Where(x => x.Id == user.Id).Single();
         AutoMapper.Mapper.Map(user, userFromDb);
         db.SubmitChanges();
    }
}
我的automapper配置是这样的
AutoMapper.Mapper.Create<User, User>().ForMember(dest => dest.Id, opt => opt.Ignore())
                                      .ForMember(dest => dest.SomeRelation, opt => opt.Ignore());
你可以在这里找到AutoMapper:http://automapper.codeplex.com/     
我让我的回购非常精益,唯一的工作就是与数据库进行交互。我在repo之上构建了一个Service层,它可以做更多的工作
public class EventRepository : IEventRepository
{

    private DBDataContext dc;
    public EventRepository()
    {
        dc = new DBDataContext();
    }

    public void Create(Event @event)
    {
        dc.Events.InsertOnSubmit(@event);
    }

    public System.Linq.IQueryable<Event> Read()
    {
        object events = (from e in dc.Eventse);
        return events.AsQueryable;
    }

    public void SubmitChanges()
    {
        dc.SubmitChanges();
    }

}
然后来自服务层的相应调用如下所示
public void AddEvent(Event @event)
{
    _EventRepository.Create(@event);
}

public void SubmitChanges()
{
    _EventRepository.SubmitChanges();
}
我从控制器那里叫它。
// AutoMapper will allow us to map the ViewModel with the DomainModel
Mapper.CreateMap<Domain.ViewModels.EventsAddViewModel, Domain.Event>();
object @event = Mapper.Map<Domain.ViewModels.EventsAddViewModel, Domain.Event>(eventToAdd);

// Add the event to the database
EventService.AddEvent(@event);
EventService.SubmitChanges();
    

要回复问题请先登录注册