C# EF代码中的静态对象和种子数据优先
这里是初学者的问题。鉴于以下情况:C# EF代码中的静态对象和种子数据优先,c#,asp.net,entity-framework,C#,Asp.net,Entity Framework,这里是初学者的问题。鉴于以下情况: public static Tenant Www = new Tenant() { TenantId = 1, Name = "www", Urls = new string[]{"https://app.com"}}; 我有一个对已定义参数的对象的引用。在这种情况下,是否假定数据库中存在具有这些值的对象 “我的种子”方法包含以下内容: if (context.Tenants.FirstOrDefault(s => s.Name ==
public static Tenant Www = new Tenant() { TenantId = 1, Name = "www", Urls = new string[]{"https://app.com"}};
我有一个对已定义参数的对象的引用。在这种情况下,是否假定数据库中存在具有这些值的对象
“我的种子”方法包含以下内容:
if (context.Tenants.FirstOrDefault(s => s.Name == "Www") == null) {
context.Tenants.Add(new Tenant() {
TenantId = 1,
Name = "Www",
Urls = new string[]{"https://app.com", "http://localhost"}
});
}
请注意,my Seed方法中的租户包含一个额外的Url
。在通过Tenant.Www
查询时,我不知道使用哪个版本
如果我通过类似于obj.TenantId=Tenant.Www.TenantId
的方式使用静态方法,我得到的结果是只使用Id,但是如果我执行类似于obj.Tenants.push(Tenant.Www)
?哪一个会被使用,为什么
是否假定数据库中存在具有这些值的对象
不,它只是Tenant
类的一个实例。在给定的代码行中没有关于此对象持久性的任何内容
我不知道在通过查询时使用哪个版本
您的Seed
方法将尝试获取Tenant
,该Name
等于“Www”
。
若在数据库中找到这样的记录,EF将具体化新的Tenant
对象,并通过数据库中的值填充其属性。从CLR的角度来看,Tenant.Www
,新物化的对象将是不同的对象。换句话说,
context.Tenants.FirstOrDefault(s => s.Name == "Www") != Tenant.Www
哪一个会被使用,为什么
同样,obj!=租户。Www
EF没有魔力。调用实体类型的构造函数时,只需创建新对象。EF上下文对您的对象一无所知,除非您通过
Add
/Attach
方法讲述它们
更新
如果您想要一些默认的租户
实例,那么:
1) 扔掉你的静态实例;
2) 定义搜索默认实例的条件(例如,Name==“Www”
);
3) 当您需要这个默认实例时,只需按照上面定义的条件从数据库中查询即可。谢谢Dennis。如果我只是为了快捷方式而尝试使用静态类,那么定义一个仅定义了TenantId的Tenant实例是否安全,这样我就可以始终通过Tenant.Www.TenantId分配关系?或者您是否建议始终执行FirstOrDefault查询以确保安全?请在您的问题上下文中定义“安全”。你到底想要这个静态实例做什么?使用id定义的方法,如果我执行push(Tenant.Www)或Add(Tenant.Www)之类的操作,我会害怕分配空的或过时的租户对象。假设static Tenant.Www只定义了一个Id,我在Add()操作中使用它,会不会因为EF找不到精确匹配而创建另一个租户?或者会使用Seed()中具有匹配Id的租户,因为EF只关心PKs吗?
Add()
操作将失败,因为entity framework将尝试获取以前未知的对象并为其创建数据库项,由于重复的Id
实体框架在Add()
操作期间未执行匹配搜索,因此将在SQL中接收插入失败。Add
仅告诉EF上下文:“看,这是一个包含数据的对象,它不存在于数据库中。当我调用SaveChanges
”时,请生成INSERT
查询。结果取决于数据库中是否存在具有相同密钥的数据以及密钥的自动递增策略。是否要定义一些默认租户
?