Entity framework DTO上的Breeze EF SaveChanges()

Entity framework DTO上的Breeze EF SaveChanges(),entity-framework,breeze,dto,Entity Framework,Breeze,Dto,我一直在与Breeze进行斗争,以保存对投影的更改,并承认我对EF和Breeze都是新手。在我之前尝试使用WCF时,也有一些类似的问题,但现在我放弃了WCF,直接将EF添加到我的解决方案中 在我的控制器中,我将元数据的DTO与DTO一起返回到breeze,它将完美绑定 更改客户端上的数据后,将调用my Breese Controller[HttpPost]SaveChanges(保存包),映射包含DTO和更改 如何保持这些更改?如果我重新读取要更新的breeze的DTO投影,则EF无法保存投影,

我一直在与Breeze进行斗争,以保存对投影的更改,并承认我对EF和Breeze都是新手。在我之前尝试使用WCF时,也有一些类似的问题,但现在我放弃了WCF,直接将EF添加到我的解决方案中

在我的控制器中,我将元数据的DTO与DTO一起返回到breeze,它将完美绑定

更改客户端上的数据后,将调用my Breese Controller[HttpPost]SaveChanges(保存包),映射包含DTO和更改

如何保持这些更改?如果我重新读取要更新的breeze的DTO投影,则EF无法保存投影,因为它未被“跟踪”,如果我读取完整实体,则breeze错误为“序列不包含匹配元素”,因为它正在查找DTO?我应该用自动制版机吗

控制器:

[BreezeController]
public class BreezeController : ApiController
{

   readonly EFContextProvider<ManiDbContext> _contextProvider = new EFContextProvider<ManiDbContext>();

    [HttpGet]
    public string Metadata()
    {
        return  _contextProvider.Metadata();
    }

    [HttpGet]
    public IQueryable<ConsigneDTO> Consignee(string refname)
    {
        return _contextProvider.Context.consigneDTO(refname);
    }

    [HttpPost]
    public SaveResult SaveChanges(JObject saveBundle)
    {
        ManiDbContextProvider _mcontextProvider = new ManiDbContextProvider();
        return  _mcontextProvider.SaveChanges(saveBundle);
    }
[BreezeController]
公共类控制器:ApiController
{
只读EFContextProvider_contextProvider=新EFContextProvider();
[HttpGet]
公共字符串元数据()
{
返回_contextProvider.Metadata();
}
[HttpGet]
公共IQueryable收货人(字符串引用名称)
{
返回_contextProvider.Context.delegatedto(refname);
}
[HttpPost]
public SaveResult SaveChanges(JObject saveBundle)
{
ManiDbContextProvider _mcontextProvider=新的ManiDbContextProvider();
返回_mcontextProvider.SaveChanges(saveBundle);
}
ManiDbContext(主DBContext是CifContext,它是数据库优先/EF反向工程)

公共类ManiDbContext:DbContext
{
public-CifContext-CifDbContext=new-CifContext();
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove();
Database.SetInitializer(null);
modelBuilder.Configurations.Add(新的委托tomap());
}
公共覆盖int SaveChanges()
{
CifDbContext.SaveChanges();
返回1;
}
公共IQueryable委托对象(字符串引用名称)
{
IQueryable q=this.CifDbContext.delegators
.Where(x=>x.Refname==Refname)
.选择(f=>new delegatedto{Refname=f.Refname,delegater=f.delegater,Address1=f.Address1,Address2=f.Address2,Address3=f.Address3});
返回q;
}
ManiDbContextProvider

    public class ManiDbContextProvider : EFContextProvider<CifContext>
//  public class ManiDbContextProvider : EFContextProvider<ManiDbContext>
  {
    public ManiDbContextProvider() : base() { }

    protected override void OpenDbConnection()
    {// do nothing
    }

    protected override void CloseDbConnection()
    { // do nothing 
    }

    protected override bool BeforeSaveEntity(EntityInfo entityInfo)
    {
        var entity = entityInfo.Entity;

        if (entity is ConsigneDTO)
        {
            return BeforeSaveConsignee(entity as ConsigneDTO, entityInfo);
        }
        throw new InvalidOperationException("Cannot save entity of unknown type");
    }

     private bool BeforeSaveConsignee(ConsigneDTO c, EntityInfo info)
    {

        var consdata = this.Context.CifDbContext.Consignes 
             .Where(x => x.Refname == c.Refname)
             .FirstOrDefault();   // ENTITY 

      //  var consdata = this.Context.consigneDTO(c.Refname); // DTO 

       return (null != consdata) || throwCannotFindConsignee();
    }
公共类ManiDbContextProvider:EFContextProvider
//公共类ManiDbContextProvider:EFContextProvider
{
public ManiDbContextProvider():base(){}
受保护的覆盖void OpenDbConnection()
{//什么也不做
}
受保护的覆盖void CloseDbConnection()
{//什么也不做
}
受保护的覆盖bool BeforeSaveEntity(EntityInfo EntityInfo)
{
var实体=entityInfo.entity;
如果(实体被委托)
{
在保存收货人之前返回(作为收货人的实体,entityInfo);
}
抛出新的InvalidOperationException(“无法保存未知类型的实体”);
}
保存收货人之前的私人bool(委托给c,实体信息)
{
var consdata=this.Context.CifDbContext.delegates
.Where(x=>x.Refname==c.Refname)
.FirstOrDefault();//实体
//var consdata=this.Context.delicatedto(c.Refname);//DTO
返回(null!=consdata)| throwCannotFindConsignee();
}
CifContext(完整列-第一个/EF反向工程/Delegate类包含键)

公共部分类CifContext:DbContext
{
静态上下文()
{
Database.SetInitializer(null);
}
公共上下文()
:base(“Name=CifContext”)
{
}
公共DbSet委托方{get;set;}
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove();//使用单数表名
Database.SetInitializer(null);
modelBuilder.Configurations.Add(新映射());
}
不管我读的是实体还是DTO,我对breeze如何更新EF一无所知

非常感谢您的帮助:)

问候,,
Mike

听起来这是一个在控制器上进行自定义保存拦截的完美案例。@PWKad感谢您的帮助,谢谢!我也这么想,如果我可以将DTO重命名为实体,那么遗憾的是breese将有能力将其全部回滚。您推荐AutoMapper吗?脑海中有好的breese示例吗?
    public class ManiDbContextProvider : EFContextProvider<CifContext>
//  public class ManiDbContextProvider : EFContextProvider<ManiDbContext>
  {
    public ManiDbContextProvider() : base() { }

    protected override void OpenDbConnection()
    {// do nothing
    }

    protected override void CloseDbConnection()
    { // do nothing 
    }

    protected override bool BeforeSaveEntity(EntityInfo entityInfo)
    {
        var entity = entityInfo.Entity;

        if (entity is ConsigneDTO)
        {
            return BeforeSaveConsignee(entity as ConsigneDTO, entityInfo);
        }
        throw new InvalidOperationException("Cannot save entity of unknown type");
    }

     private bool BeforeSaveConsignee(ConsigneDTO c, EntityInfo info)
    {

        var consdata = this.Context.CifDbContext.Consignes 
             .Where(x => x.Refname == c.Refname)
             .FirstOrDefault();   // ENTITY 

      //  var consdata = this.Context.consigneDTO(c.Refname); // DTO 

       return (null != consdata) || throwCannotFindConsignee();
    }
  public partial class CifContext : DbContext
  {
    static CifContext()
    {

        Database.SetInitializer<CifContext>(null);
    }

    public CifContext()
        : base("Name=CifContext")
    {
    }

    public DbSet<Consigne> Consignes { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();   // Use singular table names
        Database.SetInitializer<CifContext>(null);

        modelBuilder.Configurations.Add(new ConsigneMap());
     }