我正在使用Entity Framework 5构建我的第一个MVC 4/Razor Web应用程序,并在做出任何设计决策之前做了一些功课.
我看到EF对象来自EntityObject,它似乎有很多有用的最佳实践构建它,其中最重要的是乐观的并发处理.换句话说,如果2人同时装载123枫树街的简·多伊的纪录,第一个改变了她的名字简·史密斯,第二个改变了她的地址,以321枫树街,那么它很容易让被合并方面的变化在没有冲突的情况下进入记录,而第二个用户尝试修改与第一个用户相同的字段将导致错误.
在另一方面,它似乎是相当标准的做法是创建轻量级数据传输对象的服务器和客户端,并作为或型号为MVC框架之间传递数据.这对于确保最小的客户端流量非常有用,但它会破坏并发检查.
所以我质疑使用DTO的理由.使用DTO的原因是什么?使用EntityObjectas或MVC模型有多糟糕?如上所述,您建议采用哪种其他解决方案来实现乐观并发处理?
c# asp.net-mvc entity-framework asp.net-mvc-4 entity-framework-5
我收到错误:
Object graph for type 'System.Collections.Generic.List`1[[Proj.Model.Prom, Proj.Model,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]' contains cycles and cannot be
serialized if reference tracking is disabled.
Run Code Online (Sandbox Code Playgroud)
读到这一点,似乎是序列化器,但Json.Net声称是解决方案,我读过WebApi,而Framework 4.5默认使用它.所以它是默认出现的吗?如果是这样,为什么我仍然会收到该错误?
谢谢!吉列尔莫.
编辑:添加代码
using System;
using System.Collections.Generic;
using System.Data.Spatial;
namespace Proj.Model
{
public class Prom
{
public Prom()
{
this.Stores = new List<Store>();
this.Branches = new List<Branch>();
this.Products = new List<Product>();
}
public int Id { get; set; }
public string Name { get; set; }
public DbGeography Location { get; set; }
public string Latitude { get; …Run Code Online (Sandbox Code Playgroud) c# entity-framework ef-code-first asp.net-web-api entity-framework-5
我有一个场景,我想更改实体中的主键名称,并能够运行update-database -force.当我尝试时,请参阅下面的代码和错误.
实体是:
public class Team
{
[Key]
[HiddenInput(DisplayValue = false)]
public virtual int Id { get; set; }
[Display(Name = "Full Name:")]
public virtual string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
实体更改为:
public class Team
{
[Key]
[HiddenInput(DisplayValue = false)]
public virtual int TeamId { get; set; }
[Display(Name = "Full Name:")]
public virtual string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
当我运行时,Update-database -Force我得到以下错误.
Multiple identity columns specified for table 'Teams'. Only one identity column per table is …
我正在使用Entity Framework 5和Code First方法,并使用Fluent API进行实体配置.我的项目有一个特定的产品实体,它从数据库中获取一半数据,另一半来自通过WCF客户端(用于管理产品库存的第三方系统)检索的数据合同.数据合同是Product Entity类的成员(我尚未决定的属性或方法).
我不希望在实体中包含任何WCF客户端逻辑.我更喜欢将此逻辑保存在存储库代码(DbContext,DbSet等)中.
那么在从数据库中检索产品实体之后是否有一种挂钩到实体框架(或拦截)的技术?我应该注意,产品实体在其他实体上显示为导航属性.如果钩子或拦截是可能的,那么这意味着我可以在EF从数据库加载产品实体后立即从SOAP服务检索数据合同.我的项目的好处是WCF客户端检索代码不需要在整个应用程序中重复.
我的一个想法是为数据契约实现IDbSet,IDbSet将负责检索它.然后以某种方式欺骗EF认为它在产品实体上的导航属性.但我不确定数据库DbSet是否可以在同一个DbContext中与非数据库IDbSet混合.还有另外一个问题 - EF如何知道从IDbSet植入中检索导航属性?在投入时间之前,我更愿意知道这个想法是否可行.我也想知道从哪里开始寻找.
请注意我已经使用.NET超过10年,但这个EF5的东西对我来说还是比较新的.
提前致谢.
萨姆
我发现在SQL Server中存储lat和long的最佳类型是decimal(9,6)(ref.在SQL数据库中存储纬度和经度数据时使用什么数据类型?)所以我做了
AddColumn("dbo.Table", "Latitude", c => c.Decimal(nullable: false, precision: 9, scale: 6));
AddColumn("dbo.Table", "Longitude", c => c.Decimal(nullable: false, precision: 9, scale: 6));
Run Code Online (Sandbox Code Playgroud)
SQL似乎没问题,一切正常,但是当我插入/更新一个值时,即
lat = 44.5912853
Run Code Online (Sandbox Code Playgroud)
它像这样保存:
44.590000
Run Code Online (Sandbox Code Playgroud)
我检查了流程,在更新之前,我的实体包含正确的值,所以我认为不是与我的代码有关,而是与EF/SQL的一些回合有关.你有什么想法可以避免这种情况吗?
UPDATE
update [dbo].[Breweries]
set [RankId] = @0,
[Name] = @1,
[Foundation] = null,
[DirectSale] = @2,
[OnlineSale] = @3,
[StreetAddress] = @4,
[StreetAddress1] = null,
[ZIP] = @5,
[City] = @6,
[Province] = @7,
[CountryCode] = @8,
[Latitude] = @9,
[Longitude] = @10,
[PIVA] = null,
[CodFiscale] = null …Run Code Online (Sandbox Code Playgroud) 我刚刚创建了一个全新的应用程序,通过NuGet添加了EntityFramework 5,创建了一个非常基本的DbContext并保存了一些数据.
我的数据究竟在哪里?如何查看?它未App.config加修改的是
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
<parameters>
<parameter value="v11.0" />
</parameters>
</defaultConnectionFactory>
</entityFramework>
</configuration>
Run Code Online (Sandbox Code Playgroud)
通过检查db对象,我可以看到我的连接字符串是
Data Source=(localdb)\\v11.0;Initial Catalog=ImageSignature.ImageContext;Integrated Security=True;MultipleActiveResultSets=True;Application Name=EntityFrameworkMUE
Run Code Online (Sandbox Code Playgroud)
但所有这些对我来说都是胡言乱语.我来自MySQL背景.
我的数据库到底在哪里,我该如何查看?我在VS2012的"服务器资源管理器"中看不到任何相关内容.
以前使用EF 4.3并在升级到5.0时我发现索引,FK约束和PK约束都将其命名约定更改为包含dbo(例如PK_Users现在变为PK_dbo.Users)
现在,每当我对模型进行更改并且需要更改包含这些内容的表时,它总是说它不能删除约束,因为它无法找到它.
我只是想要它,以便当它试图删除约束/索引/键时,它首先检查5.0之前的命名是否存在,如果是,则删除它,但仍然使用新的5.0命名约定重新创建它.
命名约定从4.3更改为5.0:
主键/索引
Old: PK_Users New: PK_dbo.Users
Run Code Online (Sandbox Code Playgroud)
外键
Old: FK_Users_Roles_Role_Id New: FK_dbo.Users_dbo.Roles_Role_Id
Run Code Online (Sandbox Code Playgroud)
注意:我不能简单地让EF重新生成所有表,我在这个数据库中有生产数据.我也不想为每个使用自定义迁移的表手动执行此操作.
编辑:我发现了一个类似的问题如何停止添加dbo的Entity Framework 5迁移.成为关键名称?但是这个家伙只是想忽略5.0惯例并坚持使用4.3,它只处理表重命名.我不希望这样做,因为后续版本的EF可能会导致更多的更改,这些更改会影响此代码并且只是麻烦.
我试着按照发布的答案做同样的事情:
public class CodeMigrator : CSharpMigrationCodeGenerator
{
protected override void Generate(
DropIndexOperation dropIndexOperation, IndentedTextWriter writer)
{
dropIndexOperation.Name = StripDbo(dropIndexOperation.Name);
base.Generate(dropIndexOperation, writer);
}
protected override void Generate(DropForeignKeyOperation dropForeignKeyOperation, IndentedTextWriter writer)
{
dropForeignKeyOperation.Name = StripDbo(dropForeignKeyOperation.Name);
base.Generate(dropForeignKeyOperation, writer);
}
protected override void Generate(DropPrimaryKeyOperation dropPrimaryKeyOperation, IndentedTextWriter writer)
{
dropPrimaryKeyOperation.Name = StripDbo(dropPrimaryKeyOperation.Name);
base.Generate(dropPrimaryKeyOperation, writer);
}
// TODO: Override other Generate overloads that involve table …Run Code Online (Sandbox Code Playgroud) c# entity-framework ef-code-first ef-migrations entity-framework-5
我正在创建asp.net mvc4示例.在此我在datacontext的Sample表中创建了Id列作为GUID.
public class Sample
{
[Required]
public Guid ID { get; set; }
[Required]
public string FirstName { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
这是实体表
CreateTable(
"dbo.Samples",
c => new
{
ID = c.Guid(nullable: false),
FirstName = c.String(nullable: false)
})
.PrimaryKey(t => t.ID);
Run Code Online (Sandbox Code Playgroud)
Id传递00000000-0000-0000-0000-000000000000.
如何设置newid()到GUID哪里我必须设置.
我有一些代码最近从EF 4.2升级到EF 5.0(实际上是EF 4.4,因为我在.Net 4.0上运行).我发现我必须改变查询的语法,我很好奇为什么.让我从问题开始吧.
我有一个EventLog表,由客户端定期填充.对于每个事件日志,将在"报告"表中创建一个条目.这是定期运行的查询,用于发现尚未在"报告"表中包含条目的任何事件日志.我在EF 4.2中使用的查询是:
from el in _repository.EventLogs
where !_repository.Reports.Any(p => p.EventLogID == el.EventlogID)
Run Code Online (Sandbox Code Playgroud)
从升级到EF 5.0后,我在运行时收到以下错误:
System.NotSupportedException:无法创建"Namespace.Report"类型的常量值.在此上下文中仅支持基元类型或枚举类型.
我发现使用join语法重写它可以解决问题.以下适用于EF 5.0,大致相当于:
from eventLog in _repository.EventLogs
join report in _repository.Reports on eventLog.EventlogID equals report.EventLogID into alreadyReported
where !alreadyReported.Any()
Run Code Online (Sandbox Code Playgroud)
有些人可能对第一个查询的混合语法/样式有不同的看法,但我真的对这个原因更感兴趣.看起来奇怪的是EF 4.2编译器可以为原始查询生成SQL但是EF 5.0拒绝了.这是我缺少的设置还是两者之间的约束?为什么会这样?
如何在Entity Framework 5中映射以下关系?
public class Item {
public int Id { get; set; }
public int? ParentItemId { get; set; }
public string Value { get; set; }
public Item ParentItem { get; set; }
public List<Item> ChildItems { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我试过这个:
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Item>()
.HasOptional(i => i.ParentItem)
.WithMany(i => i.ChildItems)
.HasForeignKey(i => i.ParentItemId);
}
Run Code Online (Sandbox Code Playgroud)
还有这个:
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Item>()
.HasMany(i => i.ChildItems)
.WithOptional(i => i.ParentItem)
.HasForeignKey(i => i.ParentItemId); …Run Code Online (Sandbox Code Playgroud)