Mik*_*e B 22 sql oracle entity
我刚刚开始将一个应用程序从原始ADO.NET和嵌入式SQL转换为Entity.我遇到了应用程序使用的其中一个视图的问题.视图没有主键,也没有唯一标识行的列(或列组合).这是选择创建视图:
SELECT
filingmonth,
CEIL(filingmonth / 3),
licnum,
filingyear,
DECODE(GROUPING(insurername), '1', '- All Insured -', insurername),
insurername,
policylinecode,
linedescription,
SUM(NVL(grosspremium, 0)),
SUM(DECODE(taxexempt, 1, grosspremium, 0)),
TRUNC(
CASE
WHEN
(
b.rsn IS NOT NULL
OR A.zeroreport = 1
)
AND b.datereceived IS NULL
THEN A.datereceived
ELSE b.datereceived
END),
SUM(aip.iscompanyadmitted(b.naiccocode, b.naicalienid)),
A.insuredid
FROM
aip.slbtransinsured A
LEFT OUTER JOIN aip.slbtransinsurer b
ON
A.insuredid = b.insuredid
LEFT OUTER JOIN aip.slblinecodes C
ON
b.policylinecode = C.linecode
WHERE
A.submitted = 1
AND A.entryincomplete = 0
GROUP BY
licnum,
filingmonth,
filingyear,
TRUNC(
CASE
WHEN
(
b.rsn IS NOT NULL
OR A.zeroreport = 1
)
AND b.datereceived IS NULL
THEN A.datereceived
ELSE b.datereceived
END),
ROLLUP(insurername, aip.iscompanyadmitted(b.naiccocode, b.naicalienid),
policylinecode, linedescription), A.insuredid;
Run Code Online (Sandbox Code Playgroud)
这里有一些示例数据显示有些行完全重复(第3行和第4行):
FILINGMONTH CEIL(FILINGMONTH/3) LICNUM FILINGYEAR DECODE(GROUPING(INSURERNAME),'1','-ALLINSURED-',INSURERNAME) INSURERNAME POLICYLINECODE LINEDESCRIPTION SUM(NVL(GROSSPREMIUM,0)) SUM(DECODE(TAXEXEMPT,1,GROSSPREMIUM,0)) TRUNC(CASEWHEN(B.RSNISNOTNULLORA.ZEROREPORT=1)ANDB.DATERECEIVEDISNULLTHENA.DATERECEIVEDELSEB.DATERECEIVEDEND) SUM(AIP.ISCOMPANYADMITTED(B.NAICCOCODE,B.NAICALIENID)) INSUREDID
6 2 8150 2007 SAVERS PROPERTY AND CASUALTY INSURANCE CO SAVERS PROPERTY AND CASUALTY INSURANCE CO 17 OTHER LIABILITY 721.25 0 18-JUL-07 0 81
6 2 8150 2007 SAVERS PROPERTY AND CASUALTY INSURANCE CO SAVERS PROPERTY AND CASUALTY INSURANCE CO 17 721.25 0 18-JUL-07 0 81
6 2 8150 2007 SAVERS PROPERTY AND CASUALTY INSURANCE CO SAVERS PROPERTY AND CASUALTY INSURANCE CO 721.25 0 18-JUL-07 0 81
6 2 8150 2007 SAVERS PROPERTY AND CASUALTY INSURANCE CO SAVERS PROPERTY AND CASUALTY INSURANCE CO 721.25 0 18-JUL-07 0 81
Run Code Online (Sandbox Code Playgroud)
insuredid是aip.slbtransinsured表的pk,rsn是aip.slbtransinsurer和aip.slblinecodes的pk.
是否可以在没有唯一标识符的情况下向Entity模型添加视图?或者是否有一种简单的方法可以向视图添加唯一的行标识符?视图只读取,从不写入.
Mic*_*uen 33
是否可以在没有唯一标识符的情况下向Entity模型添加视图?
如果没有主键,没有.这将导致这种错误:
在模型生成期间检测到一个或多个验证错误:
System.Data.Edm.EdmEntityType :: EntityType'SalesOnEachCountry'没有定义键.定义此EntityType的键.System.Data.Edm.EdmEntitySet:EntityType:EntitySet SalesOnEachCountryList基于未定义键的SalesOnEachCountry类型.
如果没有唯一标识符,是的,尽管它具有非期望的输出.具有相同标识符的记录将引用相同的对象,这称为标识映射模式
例如,即使您的视图生成以下两行:
Country Year TotalSales
Philippines 2010 20.000000
Philippines 2011 40.000000
Run Code Online (Sandbox Code Playgroud)
如果您只是在国家/地区字段上映射主键,例如
public class SalesOnEachCountry
{
[Key]
public int CountryId { get; set; }
public string CountryName { get; set; }
public int OrYear { get; set; }
public long SalesCount { get; set; }
public decimal TotalSales { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
,即使您的视图在Oracle查询编辑器上生成上述两行,Entity Framework也会生成以下错误输出:
Country Year TotalSales
Philippines 2010 20.000000
Philippines 2010 20.000000
Run Code Online (Sandbox Code Playgroud)
实体框架将认为第二行与第一行是同一个对象.
为了保证唯一性,您必须确定使每行唯一的列.在上面的示例中,必须包含Year,因此主键是唯一的.即
public class SalesOnEachCountry
{
[Key, Column(Order=0)] public int CountryId { get; set; }
public string CountryName { get; set; }
[Key, Column(Order=1)] public int OrYear { get; set; }
public long SalesCount { get; set; }
public decimal TotalSales { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
使主键与上述属性类似,Entity Framework可以正确地将每个视图的行映射到它们自己的对象.因此,实体框架现在可以显示与视图完全相同的行.
Country Year TotalSales
Philippines 2010 20.000000
Philippines 2011 40.000000
Run Code Online (Sandbox Code Playgroud)
详情请见:http://www.ienablemuch.com/2011/06/mapping-class-to-database-view-with.html
然后,关于没有任何列以使行唯一的视图,保证实体框架可以将每个视图的行映射到它们自己的对象的最简单方法是为视图的主键创建单独的列,这是一个很好的候选者就是在每一行上创建一个行号列.例如
create view RowNumberedView as
select
row_number() over(order by <columns of your view sorting>) as RN
, *
from your_existing_view
Run Code Online (Sandbox Code Playgroud)
然后[Key]
在你的RN属性上分配属性class RowNumberedView
小智 18
扩展了Michael Buen的答案:我发现使用ISNULL()将行号添加到视图中将允许实体框架拉入视图并自动创建必要的EntitySet数据.
create view RowNumberedView as
select
ISNULL(ROW_NUMBER() OVER (ORDER BY <column>), 0) AS RN
, *
from your_existing_view
Run Code Online (Sandbox Code Playgroud)