entity-framework - 我可以先使用强类型 POCO 作为与 EF 代码的相关值,而不必每次都创建新的吗?

标签 entity-framework entity-framework-4.1 ef-code-first

我在一个类上有一个状态字段,它有一个 ID 和一个名称。我没有使用枚举来对其建模,而是使用具有一些静态值的类,如下所示:

    public class MailoutStatus : IEntity
{
    public static MailoutStatus Draft = new MailoutStatus() { Id = 1, Name = "Draft" };
    public static MailoutStatus Scheduled = new MailoutStatus() { Id = 2, Name = "Scheduled" };
    public static MailoutStatus Cancelled = new MailoutStatus() { Id = 3, Name = "Cancelled" };
    public static MailoutStatus Sent = new MailoutStatus() { Id = 4, Name = "Sent" };

    public int Id { get; set; }
    public string Name { get; set; }
...
}

现在我想在它描述的对象上设置这个状态值,像这样:

        var repo = new MailoutRepository();
        var mailout = repo.Get(1);
        mailout.Status = MailoutStatus.Cancelled;
        repo.Update(mailout);
        repo.CommitChanges();

但是,此代码会将 MailoutStatus.Cancelled 视为一个新实体,并将在 MailoutStatus 表中插入一个新行,忽略已处于 Canceled 状态的 ID 并添加一个新的 IDENTITY 生成的 ID(例如,5)。我可以通过添加 entityvalidation 东西来防止这种情况,但这只会由于验证失败而使上述内容爆炸。

我可以使用这段代码解决这个问题:

    var repo = new MailoutRepository();
    var mailout = repo.Get(1);
    mailout.Status = new MailoutStatusRepository().Get(MailoutStatus.Cancelled.Id);
    repo.Update(mailout);
    repo.CommitChanges();

这是可行的,因为现在 Entity Framework 知道我正在获取的 MailoutStatus 并正在跟踪它的状态等。但是为了设置状态而必须编写那么多代码真的很糟糕。出于其他原因,我也不想使用枚举,并且我不想让 MailoutStatus 知道任何关于持久性的信息。有什么想法吗?

最佳答案

我是这样解决的。

我定义了一个名为 NotTrackedAttribute 的属性,并将其应用于 Status 等实体。然后重写派生上下文的 SaveChanges 方法,如下所示。重置对那些实体的跟踪更改

    public override int SaveChanges()
    {
        var changedEntities = ChangeTracker.Entries();

        foreach (var changedEntity in changedEntities)
        {
             var entity = changedEntity.Entity;

             //ignore the types that are marked as NotTracked
             if (Attribute.IsDefined(entity.GetType(), typeof(NotTrackedAttribute)))
             {
                 changedEntity.State = EntityState.Unchanged;
                 continue;
             }
        }

        return base.SaveChanges();
    }

属性

/// <summary>
/// Indicates that a Type having this attribute should not be persisted.
/// </summary>
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
public class NotTrackedAttribute : Attribute
{
}

然后使用如下

[NotTracked]
public class MailoutStatus
{

}

关于entity-framework - 我可以先使用强类型 POCO 作为与 EF 代码的相关值,而不必每次都创建新的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6847905/

相关文章:

entity-framework - 在 Entity Framework 中保存一个,保存全部

entity-framework - 为什么需要在使用 .dll 作为数据访问层的消费应用程序的 app.config 文件中声明连接字符串

c# - 如何从 EF 代码优先转向更传统的开发策略?

entity-framework - 如何防止 EF 尝试在我的模型上映射方法?

entity-framework-4.1 - Entity Framework 4.1代码优先的命令超时

c# - Entity Framework Fluent API 映射

c# - 如何将复杂的 linq 映射到对象

c# - asp.net mvc 中的 LINQ + EntityFunctions

database - 如何为 Entity Framework 创建有效的连接字符串 - 底层提供程序在打开时失败?

c# - 如何从 Entity Framework 元数据 EntityType 对象中获取相应的 POCO 对象类型?